1 // Copyright 2020 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_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_H_
6 #define CHROMEOS_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_H_
7 
8 #include <ostream>
9 
10 #include "base/observer_list.h"
11 #include "base/observer_list_types.h"
12 
13 namespace chromeos {
14 namespace phonehub {
15 
16 // Exposes Instant Tethering functionality to Phone Hub.
17 class TetherController {
18  public:
19   // Note: Numerical values should stay in sync with JS enums within the debug
20   // UI at //chrome/browser/resources/chromeos/multidevice_internals/types.js.
21   enum class Status {
22     // The device is ineligible for Instant Tethering, potentially due to the
23     // flag being disabled (on Chrome OS or on the phone) or due to an
24     // enterprise policy.
25     kIneligibleForFeature = 0,
26 
27     // Instant Tethering is available for use, but currently a connection is
28     // unavailable. There are a variety of reasons why this may be the case:
29     // the feature could have been disabled in settings, the phone may not have
30     // cellular reception, or the phone may not have Google Play Services
31     // notifications enabled, which are required for the feature.
32     kConnectionUnavailable = 1,
33 
34     // It is possible to connect, but no connection is active or in progress.
35     // This state can occur if a previously-active connection has been
36     // disconnected.
37     kConnectionAvailable = 2,
38 
39     // Initiating an Instant Tethering connection.
40     kConnecting = 3,
41 
42     // Connected via Instant Tethering.
43     kConnected = 4
44   };
45 
46   class Observer : public base::CheckedObserver {
47    public:
48     ~Observer() override = default;
49 
50     // Called the status has changed; use GetStatus() to get the new status.
51     virtual void OnTetherStatusChanged() = 0;
52 
53     // Called when AttemptConnection() is called, a scan for a tether network is
54     // requested, but no tether network was found.
OnAttemptConnectionScanFailed()55     virtual void OnAttemptConnectionScanFailed() {}
56   };
57 
58   TetherController(const TetherController&) = delete;
59   TetherController& operator=(const TetherController&) = delete;
60   virtual ~TetherController();
61 
62   virtual Status GetStatus() const = 0;
63 
64   // Attempts to find an available Instant Tethering connection. For a
65   // connection to be available, the phone must be nearby, have reception, and
66   // have Google Play Services notifications enabled. This function is a no-op
67   // if the state is not kConnectionUnavailable.
68   virtual void ScanForAvailableConnection() = 0;
69 
70   // Initiates an Instant Tethering connection. This function is a no-op if the
71   // state is not one of kConnectionUnavailable or kConnectionAvailable.
72   virtual void AttemptConnection() = 0;
73 
74   // Disconnects from an active Instant Tethering connection or connection
75   // attempt. This function is a no-op if the state is not one of kConnecting or
76   // kConnected.
77   virtual void Disconnect() = 0;
78 
79   void AddObserver(Observer* observer);
80   void RemoveObserver(Observer* observer);
81 
82  protected:
83   TetherController();
84 
85   void NotifyStatusChanged();
86   void NotifyAttemptConnectionScanFailed();
87 
88  private:
89   base::ObserverList<Observer> observer_list_;
90 };
91 
92 std::ostream& operator<<(std::ostream& stream, TetherController::Status status);
93 
94 }  // namespace phonehub
95 }  // namespace chromeos
96 
97 #endif  // CHROMEOS_COMPONENTS_PHONEHUB_TETHER_CONTROLLER_H_
98