blob: ccada65a2afc8117eb193049a4ab905fc98b9fb4 [file] [log] [blame]
// 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.
#include "components/web_resource/resource_request_allowed_notifier.h"
#include "base/bind.h"
#include "base/command_line.h"
namespace web_resource {
ResourceRequestAllowedNotifier::ResourceRequestAllowedNotifier(
PrefService* local_state,
const char* disable_network_switch,
NetworkConnectionTrackerGetter network_connection_tracker_getter)
: disable_network_switch_(disable_network_switch),
local_state_(local_state),
observer_requested_permission_(false),
waiting_for_user_to_accept_eula_(false),
observer_(nullptr),
network_connection_tracker_getter_(
std::move(network_connection_tracker_getter)),
weak_factory_(this) {}
ResourceRequestAllowedNotifier::~ResourceRequestAllowedNotifier() {
if (observer_)
network_connection_tracker_->RemoveNetworkConnectionObserver(this);
}
void ResourceRequestAllowedNotifier::Init(Observer* observer, bool leaky) {
DCHECK(!observer_);
DCHECK(observer);
observer_ = observer;
DCHECK(network_connection_tracker_getter_);
network_connection_tracker_ =
std::move(network_connection_tracker_getter_).Run();
if (leaky)
network_connection_tracker_->AddLeakyNetworkConnectionObserver(this);
else
network_connection_tracker_->AddNetworkConnectionObserver(this);
if (network_connection_tracker_->GetConnectionType(
&connection_type_,
base::BindOnce(&ResourceRequestAllowedNotifier::SetConnectionType,
weak_factory_.GetWeakPtr()))) {
connection_initialized_ = true;
}
eula_notifier_.reset(CreateEulaNotifier());
if (eula_notifier_) {
eula_notifier_->Init(this);
waiting_for_user_to_accept_eula_ = !eula_notifier_->IsEulaAccepted();
}
}
ResourceRequestAllowedNotifier::State
ResourceRequestAllowedNotifier::GetResourceRequestsAllowedState() {
if (disable_network_switch_ &&
base::CommandLine::ForCurrentProcess()->HasSwitch(
disable_network_switch_)) {
return DISALLOWED_COMMAND_LINE_DISABLED;
}
// The observer requested permission. Return the current criteria state and
// set a flag to remind this class to notify the observer once the criteria
// is met.
observer_requested_permission_ =
waiting_for_user_to_accept_eula_ || IsOffline();
if (!observer_requested_permission_)
return ALLOWED;
if (waiting_for_user_to_accept_eula_)
return DISALLOWED_EULA_NOT_ACCEPTED;
if (!connection_initialized_)
return DISALLOWED_NETWORK_STATE_NOT_INITIALIZED;
return DISALLOWED_NETWORK_DOWN;
}
bool ResourceRequestAllowedNotifier::IsOffline() {
return !connection_initialized_ ||
connection_type_ == network::mojom::ConnectionType::CONNECTION_NONE;
}
bool ResourceRequestAllowedNotifier::ResourceRequestsAllowed() {
return GetResourceRequestsAllowedState() == ALLOWED;
}
void ResourceRequestAllowedNotifier::SetWaitingForEulaForTesting(bool waiting) {
waiting_for_user_to_accept_eula_ = waiting;
}
void ResourceRequestAllowedNotifier::SetObserverRequestedForTesting(
bool requested) {
observer_requested_permission_ = requested;
}
void ResourceRequestAllowedNotifier::SetConnectionTypeForTesting(
network::mojom::ConnectionType type) {
SetConnectionType(type);
}
void ResourceRequestAllowedNotifier::MaybeNotifyObserver() {
// Need to ensure that all criteria are met before notifying observers.
if (observer_requested_permission_ && ResourceRequestsAllowed()) {
DVLOG(1) << "Notifying observer of state change.";
observer_->OnResourceRequestsAllowed();
// Reset this so the observer is not informed again unless they check
// ResourceRequestsAllowed again.
observer_requested_permission_ = false;
}
}
EulaAcceptedNotifier* ResourceRequestAllowedNotifier::CreateEulaNotifier() {
return EulaAcceptedNotifier::Create(local_state_);
}
void ResourceRequestAllowedNotifier::OnEulaAccepted() {
// This flag should have been set if this was waiting on the EULA
// notification.
DCHECK(waiting_for_user_to_accept_eula_);
DVLOG(1) << "EULA was accepted.";
waiting_for_user_to_accept_eula_ = false;
MaybeNotifyObserver();
}
void ResourceRequestAllowedNotifier::OnConnectionChanged(
network::mojom::ConnectionType type) {
SetConnectionType(type);
if (type != network::mojom::ConnectionType::CONNECTION_NONE) {
DVLOG(1) << "Network came online.";
// MaybeNotifyObserver() internally guarantees that it will only notify the
// observer if it's currently waiting for the network to come online.
MaybeNotifyObserver();
}
}
void ResourceRequestAllowedNotifier::SetConnectionType(
network::mojom::ConnectionType connection_type) {
connection_type_ = connection_type;
if (!connection_initialized_) {
connection_initialized_ = true;
MaybeNotifyObserver();
}
}
} // namespace web_resource