| // Copyright 2017 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/ui/tabs/window_activity_watcher.h" |
| |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/tabs/tab_metrics_event.pb.h" |
| #include "chrome/test/base/test_browser_window.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/ukm/test_ukm_recorder.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "services/metrics/public/cpp/ukm_builders.h" |
| #include "services/metrics/public/interfaces/ukm_interface.mojom.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/ui_base_types.h" |
| |
| using metrics::WindowMetricsEvent; |
| using ukm::builders::TabManager_WindowMetrics; |
| |
| // A UKM entry consists of named metrics with int64_t values. Use a map to |
| // specify expected metrics to test against an actual entry for tests. |
| using UkmMetricMap = std::map<const char*, int64_t>; |
| |
| namespace { |
| |
| const char* kEntryName = TabManager_WindowMetrics::kEntryName; |
| |
| // TestBrowserWindow whose show state can be modified. |
| class FakeBrowserWindow : public TestBrowserWindow { |
| public: |
| FakeBrowserWindow() = default; |
| ~FakeBrowserWindow() override = default; |
| |
| // Helper function to handle FakeBrowserWindow lifetime. Modeled after |
| // CreateBrowserWithTestWindowForParams. |
| static std::unique_ptr<Browser> CreateBrowserWithFakeWindowForParams( |
| Browser::CreateParams* params) { |
| // TestBrowserWindowOwner takes ownersip of the window and will destroy the |
| // window (along with itself) automatically when the browser is closed. |
| FakeBrowserWindow* window = new FakeBrowserWindow; |
| new TestBrowserWindowOwner(window); |
| |
| params->window = window; |
| auto browser = std::make_unique<Browser>(*params); |
| window->browser_ = browser.get(); |
| return browser; |
| } |
| |
| // TestBrowserWindow: |
| bool IsMaximized() const override { |
| return show_state_ == ui::SHOW_STATE_MAXIMIZED; |
| } |
| bool IsMinimized() const override { |
| return show_state_ == ui::SHOW_STATE_MINIMIZED; |
| } |
| void Maximize() override { show_state_ = ui::SHOW_STATE_MAXIMIZED; } |
| void Minimize() override { |
| show_state_ = ui::SHOW_STATE_MINIMIZED; |
| BrowserList::NotifyBrowserNoLongerActive(browser_); |
| } |
| void Restore() override { |
| // This isn't true "restore" behavior. |
| show_state_ = ui::SHOW_STATE_NORMAL; |
| } |
| |
| private: |
| Browser* browser_; |
| ui::WindowShowState show_state_ = ui::SHOW_STATE_NORMAL; |
| |
| DISALLOW_COPY_AND_ASSIGN(FakeBrowserWindow); |
| }; |
| |
| } // namespace |
| |
| // Tests UKM entries generated by WindowMetricsLogger at the request of |
| // WindowActivityWatcher. |
| class WindowActivityWatcherTest : public testing::Test { |
| protected: |
| WindowActivityWatcherTest() = default; |
| |
| // Expects that exactly one new TabManager.WindowMetrics entry has been |
| // recorded, and that it matches the values. |
| void ExpectNewEntry(const UkmMetricMap& expected_metrics) { |
| num_entries_++; // There should only be 1 more entry than before. |
| std::vector<const ukm::mojom::UkmEntry*> entries = |
| ukm_recorder()->GetEntriesByName(kEntryName); |
| ASSERT_EQ(num_entries_, entries.size()); |
| |
| // Each expected metric should match a named value in the UKM entry. |
| const ukm::mojom::UkmEntry* entry = entries.back(); |
| for (const std::pair<const char*, uint64_t>& pair : expected_metrics) |
| ukm::TestUkmRecorder::ExpectEntryMetric(entry, pair.first, pair.second); |
| } |
| |
| bool WasNewEntryRecorded() { |
| return ukm_recorder()->GetEntriesByName(kEntryName).size() > num_entries_; |
| } |
| |
| ukm::TestUkmRecorder* ukm_recorder() { return &ukm_recorder_; } |
| Profile* profile() { return &profile_; } |
| |
| private: |
| content::TestBrowserThreadBundle test_browser_thread_bundle_; |
| ukm::TestAutoSetUkmRecorder ukm_recorder_; |
| TestingProfile profile_; |
| |
| // Tracks the expected number of entries to ensure we don't log duplicate or |
| // incorrect entries. |
| size_t num_entries_ = 0; |
| |
| DISALLOW_COPY_AND_ASSIGN(WindowActivityWatcherTest); |
| }; |
| |
| TEST_F(WindowActivityWatcherTest, Basic) { |
| WindowActivityWatcher* watcher = WindowActivityWatcher::GetInstance(); |
| |
| Browser::CreateParams params(profile(), true); |
| std::unique_ptr<Browser> browser = |
| FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms); |
| |
| watcher->CreateOrUpdateWindowMetrics(browser.get()); |
| UkmMetricMap expected_metrics({ |
| {TabManager_WindowMetrics::kWindowIdName, browser->session_id().id()}, |
| {TabManager_WindowMetrics::kShowStateName, |
| WindowMetricsEvent::SHOW_STATE_NORMAL}, |
| {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_TABBED}, |
| }); |
| { |
| SCOPED_TRACE(""); |
| ExpectNewEntry(expected_metrics); |
| } |
| |
| browser->window()->Minimize(); |
| EXPECT_TRUE(browser->window()->IsMinimized()); |
| expected_metrics[TabManager_WindowMetrics::kShowStateName] = |
| WindowMetricsEvent::SHOW_STATE_MINIMIZED; |
| { |
| SCOPED_TRACE(""); |
| ExpectNewEntry(expected_metrics); |
| } |
| |
| // A new entry is not created if nothing changes. |
| watcher->CreateOrUpdateWindowMetrics(browser.get()); |
| EXPECT_FALSE(WasNewEntryRecorded()); |
| |
| // A second browser can be logged. |
| Browser::CreateParams params_2(Browser::TYPE_POPUP, profile(), true); |
| std::unique_ptr<Browser> browser_2 = |
| FakeBrowserWindow::CreateBrowserWithFakeWindowForParams(¶ms_2); |
| |
| watcher->CreateOrUpdateWindowMetrics(browser_2.get()); |
| UkmMetricMap expected_metrics_2({ |
| {TabManager_WindowMetrics::kWindowIdName, browser_2->session_id().id()}, |
| {TabManager_WindowMetrics::kShowStateName, |
| WindowMetricsEvent::SHOW_STATE_NORMAL}, |
| {TabManager_WindowMetrics::kTypeName, WindowMetricsEvent::TYPE_POPUP}, |
| }); |
| { |
| SCOPED_TRACE(""); |
| ExpectNewEntry(expected_metrics_2); |
| } |
| } |