1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/chromeos_export.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NetworkState;
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class handles all notifications about network changes from
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// NetworkStateHandler and delegates portal detection for the active
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// network to CaptivePortalService.
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CHROMEOS_EXPORT NetworkPortalDetector {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum CaptivePortalStatus {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_UNKNOWN  = 0,
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_OFFLINE  = 1,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_ONLINE   = 2,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_PORTAL   = 3,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED = 4,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CAPTIVE_PORTAL_STATUS_COUNT
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct CaptivePortalState {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CaptivePortalState()
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : status(CAPTIVE_PORTAL_STATUS_UNKNOWN),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          response_code(net::URLFetcher::RESPONSE_CODE_INVALID) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool operator==(const CaptivePortalState& o) const {
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return status == o.status && response_code == o.response_code;
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CaptivePortalStatus status;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int response_code;
43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    base::TimeTicks time;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Observer {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Called when portal detection is completed for |network|, or
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // when observers add themselves via AddAndFireObserver(). In the
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // second case, |network| is the active network and |state| is a
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // current portal state for the active network, which can be
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // currently in the unknown state, for instance, if portal
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // detection is in process for the active network. Note, that
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // |network| may be NULL.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnPortalDetectionCompleted(
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        const NetworkState* network,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const CaptivePortalState& state) = 0;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Observer() {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Adds |observer| to the observers list.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AddObserver(Observer* observer) = 0;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Adds |observer| to the observers list and immediately calls
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // OnPortalDetectionCompleted() with the active network (which may
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // be NULL) and captive portal state for the active network (which
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // may be unknown, if, for instance, portal detection is in process
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // for the active network).
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // WARNING: don't call this method from the Observer's ctors or
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // dtors, as it implicitly calls OnPortalDetectionCompleted(), which
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is virtual.
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO (ygorshenin@): find a way to avoid this restriction.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AddAndFireObserver(Observer* observer) = 0;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removes |observer| from the observers list.
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void RemoveObserver(Observer* observer) = 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns Captive Portal state for the network specified by |service_path|.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual CaptivePortalState GetCaptivePortalState(
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& service_path) = 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if portal detection is enabled.
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsEnabled() = 0;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Enable portal detection. This method is needed because we can't
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // check current network for portal state unless user accepts EULA.
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If |start_detection| is true and NetworkPortalDetector was
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // disabled previously, portal detection for the active network is
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // initiated by this method.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Enable(bool start_detection) = 0;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Restarts portal detection for the default network if currently in
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the idle state. Returns true if new portal detection attempt was
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // started.
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool StartDetectionIfIdle() = 0;
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Sets current strategy according to |id|. If current detection id
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // doesn't equal to |id|, detection is restarted.
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) = 0;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Initializes network portal detector for testing. The
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // |network_portal_detector| will be owned by the internal pointer
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // and deleted by Shutdown().
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static void InitializeForTesting(
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      NetworkPortalDetector* network_portal_detector);
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns |true| if NetworkPortalDetector was Initialized and it is safe to
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // call Get.
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static bool IsInitialized();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Deletes the instance of the NetworkPortalDetector.
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static void Shutdown();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets the instance of the NetworkPortalDetector. Return value should
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // be used carefully in tests, because it can be changed "on the fly"
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // by calls to InitializeForTesting().
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static NetworkPortalDetector* Get();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns non-localized string representation of |status|.
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static std::string CaptivePortalStatusString(CaptivePortalStatus status);
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  NetworkPortalDetector() {}
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual ~NetworkPortalDetector() {}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static bool set_for_testing() { return set_for_testing_; }
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static NetworkPortalDetector* network_portal_detector() {
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return network_portal_detector_;
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static void set_network_portal_detector(
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NetworkPortalDetector* network_portal_detector) {
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    network_portal_detector_ = network_portal_detector;
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static bool set_for_testing_;
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static NetworkPortalDetector* network_portal_detector_;
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetector);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CHROMEOS_EXPORT NetworkPortalDetectorStubImpl
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public NetworkPortalDetector {
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NetworkPortalDetectorStubImpl();
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~NetworkPortalDetectorStubImpl();
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protected:
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // NetworkPortalDetector
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void AddObserver(Observer* observer) OVERRIDE;
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void AddAndFireObserver(Observer* observer) OVERRIDE;
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void RemoveObserver(Observer* observer) OVERRIDE;
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual CaptivePortalState GetCaptivePortalState(
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& service_path) OVERRIDE;
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool IsEnabled() OVERRIDE;
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Enable(bool start_detection) OVERRIDE;
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool StartDetectionIfIdle() OVERRIDE;
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorStubImpl);
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // CHROMEOS_NETWORK_PORTAL_DETECTOR_NETWORK_PORTAL_DETECTOR_H_
170