blob: b2c36ba0677ff0ec4e343ee115801941f9f9ded9 [file] [log] [blame]
// Copyright 2020 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 CHROME_BROWSER_LITE_VIDEO_LITE_VIDEO_DECIDER_H_
#define CHROME_BROWSER_LITE_VIDEO_LITE_VIDEO_DECIDER_H_
#include <stdint.h>
#include "base/containers/flat_set.h"
#include "base/containers/mru_cache.h"
#include "base/time/clock.h"
#include "chrome/browser/lite_video/lite_video_hint_cache.h"
#include "chrome/browser/lite_video/lite_video_user_blocklist.h"
#include "components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h"
#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
namespace blocklist {
class OptOutStore;
} // namespace blocklist
namespace optimization_guide {
class OptimizationGuideDecider;
enum class OptimizationGuideDecision;
class OptimizationMetadata;
} // namespace optimization_guide
namespace lite_video {
using LiteVideoHintCallback = base::OnceCallback<void(
absl::optional<LiteVideoHint> hint,
LiteVideoBlocklistReason blocklist_reason,
optimization_guide::OptimizationGuideDecision opt_guide_decision)>;
// The LiteVideoDecider makes the decision on whether LiteVideos should be
// applied to a navigation and provides the parameters to use when
// throttling media requests.
class LiteVideoDecider
: public blocklist::OptOutBlocklistDelegate,
public network::NetworkConnectionTracker::NetworkConnectionObserver,
public network::NetworkQualityTracker::EffectiveConnectionTypeObserver {
public:
LiteVideoDecider(
std::unique_ptr<blocklist::OptOutStore> opt_out_store,
base::Clock* clock,
optimization_guide::OptimizationGuideDecider* opt_guide_decider);
~LiteVideoDecider() override;
// Determine if the navigation can have the LiteVideo optimization applied. It
// invokes |callback| with the blocklist result and a LiteVideoHint if
// available for the |navigation_handle|. This also updates the blocklist
// based on the navigation provided and should be limited to one call per
// navigation.
void CanApplyLiteVideo(content::NavigationHandle* navigation_handle,
LiteVideoHintCallback callback);
// Override the blocklist used by |this| for testing.
void SetUserBlocklistForTesting(
std::unique_ptr<LiteVideoUserBlocklist> user_blocklist) {
user_blocklist_ = std::move(user_blocklist);
}
// Override the hint cache used by |this| for testing.
void SetHintCacheForTesting(std::unique_ptr<LiteVideoHintCache> hint_cache) {
hint_cache_ = std::move(hint_cache);
}
// blocklist::OptOutBlocklistDelegate
void OnLoadingStateChanged(bool is_loaded) override;
void OnBlocklistCleared(base::Time time) override;
// network::NetworkConnectionTracker::NetworkConnectionObserver:
void OnConnectionChanged(network::mojom::ConnectionType type) override;
// network::NetworkQualityTracker::EffectiveConnectionTypeObserver:
void OnEffectiveConnectionTypeChanged(
net::EffectiveConnectionType type) override;
// Purge all the user browsing data within |user_blocklist_| between
// the provided time ranges and all data within |cached_opt_guide_hints_|.
void ClearData(const base::Time& delete_begin, const base::Time& delete_end);
// Update |user_blocklist_| that a rebuffer event consided an opt-out on the
// mainframe and subframe URLs occurred.
void DidMediaRebuffer(const GURL& mainframe_url,
absl::optional<GURL> subframe_url,
bool opt_out);
// Set the optimization guide decider used by |this| for testing only.
void SetOptimizationGuideDeciderForTesting(
optimization_guide::OptimizationGuideDecider* opt_guide_decider) {
opt_guide_decider_ = opt_guide_decider;
}
// Set the permanently blocked hosts used by |this| for testing only.
void SetPermanentHostBlocklistForTesting(
const base::flat_set<std::string>& permanent_host_blocklist) {
permanent_host_blocklist_ = permanent_host_blocklist;
}
private:
// The result of the query to the optimization guide based on the
// |mainframe_url|.
void OnOptimizationGuideHintAvailable(
const GURL& mainframe_url,
LiteVideoBlocklistReason blocklist_reason,
LiteVideoHintCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata);
// Update the blocklists based on the navigation and the provided blocklist
// reason.
void UpdateBlocklists(content::NavigationHandle* navigation_handle,
LiteVideoBlocklistReason blocklist_reason);
// Checks the owned permanent blocklist to determine if |host|
// has been blocked from having LiteVideos shown indefinitely.
bool IsHostPermanentlyBlockedlisted(const std::string& host) const;
// The hint cache that holds LiteVideoHints that specify the parameters
// for throttling media requests for that navigation.
std::unique_ptr<LiteVideoHintCache> hint_cache_;
// The blocklist that maintains the hosts that should not have media requests
// throttled on them due to too many opt-outs.
std::unique_ptr<LiteVideoUserBlocklist> user_blocklist_;
// Whether the backing store used by the owned |user_blocklist_| is loaded
// and available.
bool blocklist_loaded_ = false;
// Whether the current network connection is cellular or not.
bool is_cellular_network_ = false;
// The current estimate of the EffectiveConnectionType.
net::EffectiveConnectionType current_effective_connection_type_ =
net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
// The optimization guide decider to consult for remote predictions.
optimization_guide::OptimizationGuideDecider* opt_guide_decider_ = nullptr;
// The store of hints provided by the optimization guide keyed by mainframe
// host. If the hint is empty, then the optimization guide returned kFalse.
base::HashingMRUCache<std::string, absl::optional<LiteVideoHint>>
cached_opt_guide_hints_;
// The set of hosts that are permanently blocked from having LiteVideos
// applied on them.
base::flat_set<std::string> permanent_host_blocklist_;
SEQUENCE_CHECKER(sequence_checker_);
// Used to get a weak pointer to |this|.
base::WeakPtrFactory<LiteVideoDecider> weak_ptr_factory_{this};
};
} // namespace lite_video
#endif // CHROME_BROWSER_LITE_VIDEO_LITE_VIDEO_DECIDER_H_