summaryrefslogtreecommitdiffstats
path: root/chrome/browser/banners/app_banner_settings_helper.h
blob: b46bc168a109de1bbe29a7bce013c68dedb4ce6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2014 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.

#ifndef CHROME_BROWSER_BANNERS_APP_BANNER_SETTINGS_HELPER_H_
#define CHROME_BROWSER_BANNERS_APP_BANNER_SETTINGS_HELPER_H_

#include <set>
#include <string>
#include <vector>

#include "base/macros.h"
#include "base/time/time.h"
#include "ui/base/page_transition_types.h"

namespace content {
class WebContents;
}  // namespace content

class GURL;
class Profile;

// Utility class to record banner events for the given package or start url.
//
// These events are used to decide when banners should be shown, using a
// heuristic based on how many different days in a recent period of time (for
// example the past two weeks) the banner could have been shown, when it was
// last shown, when it was last blocked, and when it was last installed (for
// ServiceWorker style apps - native apps can query whether the app was
// installed directly).
//
// The desired effect is to have banners appear once a user has demonstrated
// an ongoing relationship with the app, and not to pester the user too much.
//
// For most events only the last event is recorded. The exception are the
// could show events. For these a list of the events is maintained. At most
// one event is stored per day, and events outside the window the heuristic
// uses are discarded. Local times are used to enforce these rules, to ensure
// what we count as a day matches what the user perceives to be days.
class AppBannerSettingsHelper {
 public:
  enum AppBannerEvent {
    APP_BANNER_EVENT_COULD_SHOW,
    APP_BANNER_EVENT_DID_SHOW,
    APP_BANNER_EVENT_DID_BLOCK,
    APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
    APP_BANNER_EVENT_NUM_EVENTS,
  };

  enum AppBannerRapporMetric {
    WEB,
    NATIVE,
  };

  // BannerEvents record the time that a site was accessed, along with an
  // engagement weight representing the importance of the access.
  struct BannerEvent {
   base::Time time;
   double engagement;
  };

  // The content setting basically records a simplified subset of history.
  // For privacy reasons this needs to be cleared. The ClearHistoryForURLs
  // function removes any information from the banner content settings for the
  // given URls.
  static void ClearHistoryForURLs(Profile* profile,
                                  const std::set<GURL>& origin_urls);

  // Record a banner installation event, for either a WEB or NATIVE app.
  static void RecordBannerInstallEvent(
      content::WebContents* web_contents,
      const std::string& package_name_or_start_url,
      AppBannerRapporMetric rappor_metric);

  // Record a banner dismissal event, for either a WEB or NATIVE app.
  static void RecordBannerDismissEvent(
      content::WebContents* web_contents,
      const std::string& package_name_or_start_url,
      AppBannerRapporMetric rappor_metric);

  // Record a banner event. Should not be used for could show events, as they
  // require a transition type.
  static void RecordBannerEvent(content::WebContents* web_contents,
                                const GURL& origin_url,
                                const std::string& package_name_or_start_url,
                                AppBannerEvent event,
                                base::Time time);

  // Record a banner could show event, with a specified transition type.
  static void RecordBannerCouldShowEvent(
      content::WebContents* web_contents,
      const GURL& origin_url,
      const std::string& package_name_or_start_url,
      base::Time time,
      ui::PageTransition transition_type);

  // Determine if the banner should be shown, given the recorded events for the
  // supplied app.
  static bool ShouldShowBanner(content::WebContents* web_contents,
                               const GURL& origin_url,
                               const std::string& package_name_or_start_url,
                               base::Time time);

  // Gets the could have been shown events that are stored for the given package
  // or start url. This is only exposed for testing.
  static std::vector<BannerEvent> GetCouldShowBannerEvents(
      content::WebContents* web_contents,
      const GURL& origin_url,
      const std::string& package_name_or_start_url);

  // Get the recorded event for an event type that only records the last event.
  // Should not be used with APP_BANNER_EVENT_COULD_SHOW. This is only exposed
  // for testing.
  static base::Time GetSingleBannerEvent(
      content::WebContents* web_contents,
      const GURL& origin_url,
      const std::string& package_name_or_start_url,
      AppBannerEvent event);

  // Record a UMA statistic measuring the minutes between the first visit to the
  // site and the first showing of the banner.
  static void RecordMinutesFromFirstVisitToShow(
      content::WebContents* web_contents,
      const GURL& origin_url,
      const std::string& package_name_or_start_url,
      base::Time time);

  // Set the engagement weights assigned to direct and indirect navigations.
  static void SetEngagementWeights(double direct_engagement,
                                   double indirect_engagement);

  // Set the minimum number of minutes between banner visits that will
  // trigger a could show banner event. This must be less than the
  // number of minutes in a day, and evenly divide the number of minutes
  // in a day.
  static void SetMinimumMinutesBetweenVisits(unsigned int minutes);

  // Set the total engagement weight required to trigger a banner.
  static void SetTotalEngagementToTrigger(double total_engagement);

  // Bucket a given time to the given resolution in local time.
  static base::Time BucketTimeToResolution(base::Time time,
                                           unsigned int minutes);

  // Updates all values from field trial.
  static void UpdateFromFieldTrial();

  // Returns true if the app banner trigger condition should use the site
  // engagement score instead of the navigation-based heuristic.
  static bool ShouldUseSiteEngagementScore();

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(AppBannerSettingsHelper);
};

#endif  // CHROME_BROWSER_BANNERS_APP_BANNER_SETTINGS_HELPER_H_