1// Copyright 2014 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 CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
6#define CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
7
8#include "base/basictypes.h"
9#include "chromeos/chromeos_export.h"
10#include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
11#include "net/url_request/url_fetcher.h"
12
13namespace chromeos {
14
15class NetworkState;
16
17// This class handles all notifications about network changes from
18// NetworkStateHandler and delegates portal detection for the active
19// network to CaptivePortalService.
20class CHROMEOS_EXPORT NetworkPortalDetector {
21 public:
22  enum CaptivePortalStatus {
23    CAPTIVE_PORTAL_STATUS_UNKNOWN  = 0,
24    CAPTIVE_PORTAL_STATUS_OFFLINE  = 1,
25    CAPTIVE_PORTAL_STATUS_ONLINE   = 2,
26    CAPTIVE_PORTAL_STATUS_PORTAL   = 3,
27    CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED = 4,
28    CAPTIVE_PORTAL_STATUS_COUNT
29  };
30
31  struct CaptivePortalState {
32    CaptivePortalState()
33        : status(CAPTIVE_PORTAL_STATUS_UNKNOWN),
34          response_code(net::URLFetcher::RESPONSE_CODE_INVALID) {
35    }
36
37    bool operator==(const CaptivePortalState& o) const {
38      return status == o.status && response_code == o.response_code;
39    }
40
41    CaptivePortalStatus status;
42    int response_code;
43    base::TimeTicks time;
44  };
45
46  class Observer {
47   public:
48    // Called when portal detection is completed for |network|, or
49    // when observers add themselves via AddAndFireObserver(). In the
50    // second case, |network| is the active network and |state| is a
51    // current portal state for the active network, which can be
52    // currently in the unknown state, for instance, if portal
53    // detection is in process for the active network. Note, that
54    // |network| may be NULL.
55    virtual void OnPortalDetectionCompleted(
56        const NetworkState* network,
57        const CaptivePortalState& state) = 0;
58
59   protected:
60    virtual ~Observer() {}
61  };
62
63  // Adds |observer| to the observers list.
64  virtual void AddObserver(Observer* observer) = 0;
65
66  // Adds |observer| to the observers list and immediately calls
67  // OnPortalDetectionCompleted() with the active network (which may
68  // be NULL) and captive portal state for the active network (which
69  // may be unknown, if, for instance, portal detection is in process
70  // for the active network).
71  //
72  // WARNING: don't call this method from the Observer's ctors or
73  // dtors, as it implicitly calls OnPortalDetectionCompleted(), which
74  // is virtual.
75  // TODO (ygorshenin@): find a way to avoid this restriction.
76  virtual void AddAndFireObserver(Observer* observer) = 0;
77
78  // Removes |observer| from the observers list.
79  virtual void RemoveObserver(Observer* observer) = 0;
80
81  // Returns Captive Portal state for the network specified by |service_path|.
82  virtual CaptivePortalState GetCaptivePortalState(
83      const std::string& service_path) = 0;
84
85  // Returns true if portal detection is enabled.
86  virtual bool IsEnabled() = 0;
87
88  // Enable portal detection. This method is needed because we can't
89  // check current network for portal state unless user accepts EULA.
90  // If |start_detection| is true and NetworkPortalDetector was
91  // disabled previously, portal detection for the active network is
92  // initiated by this method.
93  virtual void Enable(bool start_detection) = 0;
94
95  // Restarts portal detection for the default network if currently in
96  // the idle state. Returns true if new portal detection attempt was
97  // started.
98  virtual bool StartDetectionIfIdle() = 0;
99
100  // Sets current strategy according to |id|. If current detection id
101  // doesn't equal to |id|, detection is restarted.
102  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) = 0;
103
104  // Initializes network portal detector for testing. The
105  // |network_portal_detector| will be owned by the internal pointer
106  // and deleted by Shutdown().
107  static void InitializeForTesting(
108      NetworkPortalDetector* network_portal_detector);
109
110  // Returns |true| if NetworkPortalDetector was Initialized and it is safe to
111  // call Get.
112  static bool IsInitialized();
113
114  // Deletes the instance of the NetworkPortalDetector.
115  static void Shutdown();
116
117  // Gets the instance of the NetworkPortalDetector. Return value should
118  // be used carefully in tests, because it can be changed "on the fly"
119  // by calls to InitializeForTesting().
120  static NetworkPortalDetector* Get();
121
122  // Returns non-localized string representation of |status|.
123  static std::string CaptivePortalStatusString(CaptivePortalStatus status);
124
125 protected:
126  NetworkPortalDetector() {}
127  virtual ~NetworkPortalDetector() {}
128
129  static bool set_for_testing() { return set_for_testing_; }
130  static NetworkPortalDetector* network_portal_detector() {
131    return network_portal_detector_;
132  }
133  static void set_network_portal_detector(
134      NetworkPortalDetector* network_portal_detector) {
135    network_portal_detector_ = network_portal_detector;
136  }
137
138 private:
139  static bool set_for_testing_;
140  static NetworkPortalDetector* network_portal_detector_;
141
142  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetector);
143};
144
145class CHROMEOS_EXPORT NetworkPortalDetectorStubImpl
146    : public NetworkPortalDetector {
147 public:
148  NetworkPortalDetectorStubImpl();
149  virtual ~NetworkPortalDetectorStubImpl();
150
151 protected:
152  // NetworkPortalDetector
153  virtual void AddObserver(Observer* observer) OVERRIDE;
154  virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
155  virtual void RemoveObserver(Observer* observer) OVERRIDE;
156  virtual CaptivePortalState GetCaptivePortalState(
157      const std::string& service_path) OVERRIDE;
158  virtual bool IsEnabled() OVERRIDE;
159  virtual void Enable(bool start_detection) OVERRIDE;
160  virtual bool StartDetectionIfIdle() OVERRIDE;
161  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
162
163 private:
164  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorStubImpl);
165};
166
167}  // namespace chromeos
168
169#endif  // CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
170