1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_METRICS_H_
6 #define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_METRICS_H_
7 
8 #include "base/memory/weak_ptr.h"
9 #include "base/power_monitor/power_observer.h"
10 #include "base/scoped_observer.h"
11 #include "chrome/browser/banners/app_banner_manager.h"
12 #include "chrome/browser/engagement/site_engagement_observer.h"
13 #include "chrome/browser/ui/browser_tab_strip_tracker.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
15 #include "chrome/browser/web_applications/components/web_app_id.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 
18 class Profile;
19 class Browser;
20 class TabStripModel;
21 
22 namespace content {
23 class WebContents;
24 }  // namespace content
25 
26 namespace web_app {
27 
28 // A per-profile keyed service, responsible for all Web Applications-related
29 // metrics recording (UMA histograms and UKM keyed by web-apps).
30 class WebAppMetrics : public KeyedService,
31                       public SiteEngagementObserver,
32                       public BrowserListObserver,
33                       public TabStripModelObserver,
34                       public banners::AppBannerManager::Observer,
35                       public base::PowerObserver {
36  public:
37   static WebAppMetrics* Get(Profile* profile);
38 
39   explicit WebAppMetrics(Profile* profile);
40   WebAppMetrics(const WebAppMetrics&) = delete;
41   WebAppMetrics& operator=(const WebAppMetrics&) = delete;
42   ~WebAppMetrics() override;
43 
44   // SiteEngagementObserver:
45   void OnEngagementEvent(
46       content::WebContents* web_contents,
47       const GURL& url,
48       double score,
49       SiteEngagementService::EngagementType engagement_type) override;
50 
51   // BrowserListObserver:
52   void OnBrowserNoLongerActive(Browser* browser) override;
53   void OnBrowserSetLastActive(Browser* browser) override;
54 
55   // TabStripModelObserver for all Browsers:
56   void OnTabStripModelChanged(
57       TabStripModel* tab_strip_model,
58       const TabStripModelChange& change,
59       const TabStripSelectionChange& selection) override;
60 
61   // base::PowerObserver:
62   void OnSuspend() override;
63 
64   // Called when a web contents changes associated AppId (may be empty).
65   void NotifyOnAssociatedAppChanged(content::WebContents* web_contents,
66                                     const AppId& previous_app_id,
67                                     const AppId& new_app_id);
68 
69   // banners::AppBannerManager::Observer:
70   void OnInstallableWebAppStatusUpdated() override;
71 
72   // Browser activation causes flaky tests. Call observer methods directly.
73   void RemoveBrowserListObserverForTesting();
74   void CountUserInstalledAppsForTesting();
75 
76  private:
77   void CountUserInstalledApps();
78   enum class TabSwitching { kFrom, kTo, kBackgroundClosing };
79   void UpdateUkmData(content::WebContents* web_contents, TabSwitching mode);
80   void UpdateForegroundWebContents(content::WebContents* web_contents);
81 
82   // Calculate number of user installed apps once on start to avoid cpu costs
83   // in OnEngagementEvent: sacrifice histograms accuracy for speed.
84   static constexpr int kNumUserInstalledAppsNotCounted = -1;
85   int num_user_installed_apps_ = kNumUserInstalledAppsNotCounted;
86 
87   base::flat_map<web_app::AppId, base::Time> app_last_interacted_time_{};
88   content::WebContents* foreground_web_contents_ = nullptr;
89   GURL last_recorded_web_app_start_url_;
90 
91   Profile* const profile_;
92 
93   BrowserTabStripTracker browser_tab_strip_tracker_;
94   ScopedObserver<banners::AppBannerManager, banners::AppBannerManager::Observer>
95       app_banner_manager_observer_{this};
96 
97   base::WeakPtrFactory<WebAppMetrics> weak_ptr_factory_{this};
98 
99 };
100 
101 }  // namespace web_app
102 
103 #endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_METRICS_H_
104