summaryrefslogtreecommitdiff
path: root/chromium/components/web_resource/resource_request_allowed_notifier.h
blob: fff25e8e6341473f479a282e9d379f58d7f89d3d (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
// Copyright 2013 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 COMPONENTS_WEB_RESOURCE_RESOURCE_REQUEST_ALLOWED_NOTIFIER_H_
#define COMPONENTS_WEB_RESOURCE_RESOURCE_REQUEST_ALLOWED_NOTIFIER_H_

#include <memory>

#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "components/web_resource/eula_accepted_notifier.h"
#include "services/network/public/cpp/network_connection_tracker.h"

class PrefService;

namespace web_resource {

// This class informs an interested observer when resource requests over the
// network are permitted.
//
// Currently, the criteria for allowing resource requests are:
//  1. The network is currently available,
//  2. The EULA was accepted by the user (ChromeOS only), and
//  3. The --disable-background-networking command line switch is not set.
//
// Interested services should add themselves as an observer of
// ResourceRequestAllowedNotifier and check ResourceRequestsAllowed() to see if
// requests are permitted. If it returns true, they can go ahead and make their
// request. If it returns false, ResourceRequestAllowedNotifier will notify the
// service when the criteria is met.
//
// If ResourceRequestsAllowed returns true the first time,
// ResourceRequestAllowedNotifier will not notify the service in the future.
//
// Note that this class handles the criteria state for a single service, so
// services should keep their own instance of this class rather than sharing a
// global instance.
class ResourceRequestAllowedNotifier
    : public EulaAcceptedNotifier::Observer,
      public network::NetworkConnectionTracker::NetworkConnectionObserver {
 public:
  // Observes resource request allowed state changes.
  class Observer {
   public:
    virtual void OnResourceRequestsAllowed() = 0;
    virtual ~Observer() = default;
  };

  // Specifies the resource request allowed state.
  enum State {
    ALLOWED,
    DISALLOWED_EULA_NOT_ACCEPTED,
    DISALLOWED_NETWORK_DOWN,
    DISALLOWED_COMMAND_LINE_DISABLED,
    DISALLOWED_NETWORK_STATE_NOT_INITIALIZED,
  };

  using NetworkConnectionTrackerGetter =
      base::OnceCallback<network::NetworkConnectionTracker*()>;

  // Creates a new ResourceRequestAllowedNotifier.
  // |local_state| is the PrefService to observe.
  // |disable_network_switch| is the command line switch to disable network
  // activity. It is expected to outlive the ResourceRequestAllowedNotifier and
  // may be null.
  ResourceRequestAllowedNotifier(
      PrefService* local_state,
      const char* disable_network_switch,
      NetworkConnectionTrackerGetter network_connection_tracker_getter);

  ResourceRequestAllowedNotifier(const ResourceRequestAllowedNotifier&) =
      delete;
  ResourceRequestAllowedNotifier& operator=(
      const ResourceRequestAllowedNotifier&) = delete;

  ~ResourceRequestAllowedNotifier() override;

  // Sets |observer| as the service to be notified by this instance, and
  // performs initial checks on the criteria. |observer| may not be null.
  // This is to be called immediately after construction of an instance of
  // ResourceRequestAllowedNotifier to pass it the interested service. Set
  // |leaky| to true if this class will not be destructed before shutdown.
  void Init(Observer* observer, bool leaky);

  // Returns whether resource requests are allowed, per the various criteria.
  // If not, this call will set some flags so it knows to notify the observer
  // if the criteria change. Note that the observer will not be notified unless
  // it calls this method first.
  // This is virtual so it can be overridden for tests.
  virtual State GetResourceRequestsAllowedState();

  // Convenience function, equivalent to:
  //   GetResourceRequestsAllowedState() == ALLOWED.
  bool ResourceRequestsAllowed();

  void SetWaitingForEulaForTesting(bool waiting);
  void SetObserverRequestedForTesting(bool requested);
  void SetConnectionTypeForTesting(
      network::mojom::ConnectionType connection_type);

 protected:
  // Notifies the observer if all criteria needed for resource requests are met.
  // This is protected so it can be called from subclasses for testing.
  void MaybeNotifyObserver();

 private:
  // Creates the EulaAcceptNotifier or null if one is not needed. Virtual so
  // that it can be overridden by test subclasses.
  virtual EulaAcceptedNotifier* CreateEulaNotifier();

  // EulaAcceptedNotifier::Observer overrides:
  void OnEulaAccepted() override;

  // network::NetworkConnectionTracker::NetworkConnectionObserver overrides:
  void OnConnectionChanged(network::mojom::ConnectionType type) override;

  void SetConnectionType(network::mojom::ConnectionType connection_type);
  bool IsOffline();

  // Name of the command line switch to disable the network activity.
  const char* disable_network_switch_;

  // The local state this class is observing.
  raw_ptr<PrefService> local_state_;

  // Tracks whether or not the observer/service depending on this class actually
  // requested permission to make a request or not. If it did not, then this
  // class should not notify it even if the criteria is met.
  bool observer_requested_permission_;

  // Tracks EULA acceptance criteria.
  bool waiting_for_user_to_accept_eula_;

  // Platform-specific notifier of EULA acceptance, or null if not needed.
  std::unique_ptr<EulaAcceptedNotifier> eula_notifier_;

  // Observing service interested in request permissions.
  raw_ptr<Observer> observer_;

  NetworkConnectionTrackerGetter network_connection_tracker_getter_;
  raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_ =
      nullptr;
  network::mojom::ConnectionType connection_type_ =
      network::mojom::ConnectionType::CONNECTION_UNKNOWN;
  bool connection_initialized_ = false;

  base::WeakPtrFactory<ResourceRequestAllowedNotifier> weak_factory_{this};
};

extern const base::Feature kResourceRequestAllowedMigration;

}  // namespace web_resource

#endif  // COMPONENTS_WEB_RESOURCE_RESOURCE_REQUEST_ALLOWED_NOTIFIER_H_