summaryrefslogtreecommitdiffstats
path: root/chrome/browser/web_resource/notification_promo.h
blob: 7f2aa58707044439b2d14f420c76496e0f545280 (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
157
158
159
160
161
162
163
164
165
166
167
// Copyright (c) 2011 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_WEB_RESOURCE_NOTIFICATION_PROMO_H_
#define CHROME_BROWSER_WEB_RESOURCE_NOTIFICATION_PROMO_H_
#pragma once

#include <string>

#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"

namespace base {
  class DictionaryValue;
}

namespace net {
  class URLRequestContextGetter;
}

class PrefService;
class Profile;

// Helper class for PromoResourceService that parses promo notification info
// from json or prefs.
class NotificationPromo
  : public base::RefCountedThreadSafe<NotificationPromo> {
 public:
  class Delegate {
   public:
     virtual ~Delegate() {}
     virtual void OnNotificationParsed(double start, double end,
                                       bool new_notification) = 0;
     // For testing.
     virtual bool IsBuildAllowed(int builds_targeted) const { return false; }
     virtual int CurrentPlatform() const { return PLATFORM_NONE; }
  };

  // Static factory for creating new notification promos.
  static NotificationPromo* Create(Profile* profile, Delegate* delegate);

  // Initialize from json/prefs.
  void InitFromJson(const base::DictionaryValue& json, bool do_cookie_check);
  void InitFromPrefs();

  // Can this promo be shown?
  bool CanShow() const;

  // Calculates promo notification start time with group-based time slice
  // offset.
  double StartTimeWithOffset() const;

  // Helpers for NewTabPageHandler.
  void HandleClosed();
  bool HandleViewed();  // returns true if views exceeds maximum allowed.

  // Register preferences.
  static void RegisterUserPrefs(PrefService* prefs);

 private:
  friend class base::RefCountedThreadSafe<NotificationPromo>;
  NotificationPromo(Profile* profile, Delegate* delegate);
  virtual ~NotificationPromo();

  // For testing.
  friend class NotificationPromoTestDelegate;
  FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, GetNextQuestionValueTest);
  FRIEND_TEST_ALL_PREFIXES(PromoResourceServiceTest, NewGroupTest);

  enum PlatformType {
    PLATFORM_NONE = 0,
    PLATFORM_WIN = 1,
    PLATFORM_MAC = 1 << 1,
    PLATFORM_LINUX = 1 << 2,
    PLATFORM_CHROMEOS = 1 << 3,
    PLATFORM_ALL = (1 << 4) -1,
  };

  // Flags for feature_mask_.
  enum Feature {
    NO_FEATURE = 0,
    FEATURE_GPLUS = 1,
  };

  // Users are randomly assigned to one of kMaxGroupSize + 1 buckets, in order
  // to be able to roll out promos slowly, or display different promos to
  // different groups.
  static const int kMaxGroupSize = 99;

  // Parse the answers array element. Set the data members of this instance
  // and trigger OnNewNotification callback if necessary.
  void Parse(const base::DictionaryValue* dict);

  // Set promo notification params from a question string, which is of the form
  // <build_type>:<time_slice>:<max_group>:<max_views>:<platform>:<feature_mask>
  void ParseParams(const base::DictionaryValue* dict);

  // Check if this promo notification is new based on start/end times,
  // and trigger events accordingly.
  void CheckForNewNotification(bool found_cookie);

  // Actions on receiving a new promo notification.
  void OnNewNotification();

  // Async method to get cookies from GPlus url. Used to check if user is
  // logged in to GPlus.
  void GetCookies(scoped_refptr<net::URLRequestContextGetter> getter);

  // Callback for GetCookies.
  void GetCookiesCallback(const std::string& cookies);

  // Parse cookies in search of a SID= value.
  static bool CheckForGPlusCookie(const std::string& cookies);

  // Create a new promo notification group.
  static int NewGroup();

  // Returns an int converted from the question substring starting at index
  // till the next colon. Sets index to the location right after the colon.
  // Returns 0 if *err is true, and sets *err to true upon error.
  static int GetNextQuestionValue(const std::string& question,
                                  size_t* index,
                                  bool* err);

  // Flush data members to prefs for storage.
  void WritePrefs();

  // Match our channel with specified build type.
  bool IsBuildAllowed(int builds_allowed) const;

  // Match our platform with the specified platform bitfield.
  bool IsPlatformAllowed(int target_platform) const;

  // Current platform.
  static int CurrentPlatform();

  // For testing.
  bool operator==(const NotificationPromo& other) const;

  Profile* profile_;
  Delegate* delegate_;
  PrefService* prefs_;

  double start_;
  double end_;

  int build_;
  int time_slice_;
  int max_group_;
  int max_views_;
  int platform_;
  int feature_mask_;

  int group_;
  int views_;
  std::string text_;
  bool closed_;
  bool gplus_;

  DISALLOW_COPY_AND_ASSIGN(NotificationPromo);
};

#endif  // CHROME_BROWSER_WEB_RESOURCE_NOTIFICATION_PROMO_H_