forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[fuchsia] Implement NavigationPolicyThrottle for navigation blocking
* Add an implementation of NavigationPolicyThrottle to WebEngine * Add NavigationPolicyHandler, which keeps track of throttles and checks if navigations need to be passed on to the client * Add a FakeNavigationPolicyProvider for tests Test: NavigationPolicyThrottleTest Bug: 1117601 Change-Id: I0bdf94345b10d829bea4aeb85f74204970a97239 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2519039 Commit-Queue: Sharon Yang <[email protected]> Reviewed-by: Sergey Ulanov <[email protected]> Cr-Commit-Position: refs/heads/master@{#826625}
- Loading branch information
1 parent
bea2652
commit 17bbb4d
Showing
8 changed files
with
464 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// 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. | ||
|
||
#include "fuchsia/engine/browser/fake_navigation_policy_provider.h" | ||
|
||
#include "base/logging.h" | ||
#include "base/notreached.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
FakeNavigationPolicyProvider::FakeNavigationPolicyProvider() = default; | ||
|
||
FakeNavigationPolicyProvider::~FakeNavigationPolicyProvider() = default; | ||
|
||
void FakeNavigationPolicyProvider::EvaluateRequestedNavigation( | ||
fuchsia::web::RequestedNavigation requested_navigation, | ||
EvaluateRequestedNavigationCallback callback) { | ||
fuchsia::web::NavigationDecision decision; | ||
if (should_reject_request_) { | ||
callback(decision.WithAbort(fuchsia::web::NoArgumentsAction())); | ||
} else { | ||
callback(decision.WithProceed(fuchsia::web::NoArgumentsAction())); | ||
} | ||
|
||
requested_navigation_ = std::move(requested_navigation); | ||
} | ||
|
||
void FakeNavigationPolicyProvider::NotImplemented_(const std::string& name) { | ||
NOTIMPLEMENTED() << name; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// 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 FUCHSIA_ENGINE_BROWSER_FAKE_NAVIGATION_POLICY_PROVIDER_H_ | ||
#define FUCHSIA_ENGINE_BROWSER_FAKE_NAVIGATION_POLICY_PROVIDER_H_ | ||
|
||
#include <fuchsia/web/cpp/fidl.h> | ||
#include <fuchsia/web/cpp/fidl_test_base.h> | ||
|
||
class FakeNavigationPolicyProvider | ||
: public fuchsia::web::testing::NavigationPolicyProvider_TestBase { | ||
public: | ||
FakeNavigationPolicyProvider(); | ||
~FakeNavigationPolicyProvider() override; | ||
|
||
FakeNavigationPolicyProvider(const FakeNavigationPolicyProvider&) = delete; | ||
FakeNavigationPolicyProvider& operator=(const FakeNavigationPolicyProvider&) = | ||
delete; | ||
|
||
void set_should_reject_request(bool reject) { | ||
should_reject_request_ = reject; | ||
} | ||
|
||
fuchsia::web::RequestedNavigation* requested_navigation() { | ||
return &requested_navigation_; | ||
} | ||
|
||
// fuchsia::web::NavigationPolicyProvider implementation. | ||
void EvaluateRequestedNavigation( | ||
fuchsia::web::RequestedNavigation requested_navigation, | ||
EvaluateRequestedNavigationCallback callback) final; | ||
void NotImplemented_(const std::string& name) final; | ||
|
||
private: | ||
fuchsia::web::RequestedNavigation requested_navigation_; | ||
bool should_reject_request_ = false; | ||
}; | ||
|
||
#endif // FUCHSIA_ENGINE_BROWSER_FAKE_NAVIGATION_POLICY_PROVIDER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// 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. | ||
|
||
#include "fuchsia/engine/browser/navigation_policy_handler.h" | ||
|
||
#include <lib/fidl/cpp/binding.h> | ||
|
||
#include "base/fuchsia/fuchsia_logging.h" | ||
#include "content/public/browser/navigation_handle.h" | ||
#include "fuchsia/engine/browser/navigation_policy_throttle.h" | ||
|
||
NavigationPolicyHandler::NavigationPolicyHandler( | ||
fuchsia::web::NavigationPolicyProviderParams params, | ||
fidl::InterfaceHandle<fuchsia::web::NavigationPolicyProvider> delegate) | ||
: params_(std::move(params)), provider_(delegate.Bind()) { | ||
provider_.set_error_handler(fit::bind_member( | ||
this, &NavigationPolicyHandler::OnNavigationPolicyProviderDisconnected)); | ||
} | ||
|
||
NavigationPolicyHandler::~NavigationPolicyHandler() { | ||
for (auto* throttle : navigation_throttles_) { | ||
throttle->OnNavigationPolicyProviderDisconnected( | ||
content::NavigationThrottle::CANCEL); | ||
} | ||
navigation_throttles_.clear(); | ||
} | ||
|
||
void NavigationPolicyHandler::RegisterNavigationThrottle( | ||
NavigationPolicyThrottle* navigation_throttle) { | ||
navigation_throttles_.insert(navigation_throttle); | ||
} | ||
|
||
void NavigationPolicyHandler::RemoveNavigationThrottle( | ||
NavigationPolicyThrottle* navigation_throttle) { | ||
navigation_throttles_.erase(navigation_throttle); | ||
} | ||
|
||
void NavigationPolicyHandler::EvaluateRequestedNavigation( | ||
fuchsia::web::RequestedNavigation requested_navigation, | ||
fuchsia::web::NavigationPolicyProvider::EvaluateRequestedNavigationCallback | ||
callback) { | ||
provider_->EvaluateRequestedNavigation(std::move(requested_navigation), | ||
std::move(callback)); | ||
} | ||
|
||
bool NavigationPolicyHandler::ShouldEvaluateNavigation( | ||
content::NavigationHandle* handle, | ||
fuchsia::web::NavigationPhase phase) { | ||
if (handle->IsInMainFrame()) { | ||
return (phase & params_.main_frame_phases()) == phase; | ||
} | ||
|
||
return (phase & params_.subframe_phases()) == phase; | ||
} | ||
|
||
bool NavigationPolicyHandler::is_provider_connected() { | ||
return provider_.is_bound(); | ||
} | ||
|
||
void NavigationPolicyHandler::OnNavigationPolicyProviderDisconnected( | ||
zx_status_t status) { | ||
ZX_LOG(ERROR, status) << "NavigationPolicyProvider disconnected"; | ||
for (auto* throttle : navigation_throttles_) { | ||
throttle->OnNavigationPolicyProviderDisconnected( | ||
content::NavigationThrottle::CANCEL); | ||
} | ||
navigation_throttles_.clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// 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 FUCHSIA_ENGINE_BROWSER_NAVIGATION_POLICY_HANDLER_H_ | ||
#define FUCHSIA_ENGINE_BROWSER_NAVIGATION_POLICY_HANDLER_H_ | ||
|
||
#include <fuchsia/web/cpp/fidl.h> | ||
|
||
#include "base/containers/flat_set.h" | ||
|
||
class NavigationPolicyThrottle; | ||
|
||
namespace content { | ||
class NavigationHandle; | ||
} // namespace content | ||
|
||
class NavigationPolicyHandler { | ||
public: | ||
NavigationPolicyHandler( | ||
fuchsia::web::NavigationPolicyProviderParams params, | ||
fidl::InterfaceHandle<fuchsia::web::NavigationPolicyProvider> delegate); | ||
~NavigationPolicyHandler(); | ||
|
||
NavigationPolicyHandler(const NavigationPolicyHandler&) = delete; | ||
NavigationPolicyHandler& operator=(const NavigationPolicyHandler&) = delete; | ||
|
||
void RegisterNavigationThrottle( | ||
NavigationPolicyThrottle* navigation_throttle); | ||
void RemoveNavigationThrottle(NavigationPolicyThrottle* navigation_throttle); | ||
|
||
fuchsia::web::NavigationPolicyProvider* navigation_policy_provider() { | ||
return provider_.get(); | ||
} | ||
|
||
bool is_provider_connected(); | ||
|
||
// Passes on the call to |provider_|. | ||
void EvaluateRequestedNavigation( | ||
fuchsia::web::RequestedNavigation requested_navigation, | ||
fuchsia::web::NavigationPolicyProvider:: | ||
EvaluateRequestedNavigationCallback callback); | ||
|
||
// Determines whether or not the client is interested in evaluating |handle|. | ||
bool ShouldEvaluateNavigation(content::NavigationHandle* handle, | ||
fuchsia::web::NavigationPhase phase); | ||
|
||
private: | ||
void OnNavigationPolicyProviderDisconnected(zx_status_t status); | ||
|
||
fuchsia::web::NavigationPolicyProviderParams params_; | ||
fuchsia::web::NavigationPolicyProviderPtr provider_; | ||
|
||
// Keeps track of the NavigationThrottles associated with the Frame that owns | ||
// |this|. | ||
base::flat_set<NavigationPolicyThrottle*> navigation_throttles_; | ||
}; | ||
|
||
#endif // FUCHSIA_ENGINE_BROWSER_NAVIGATION_POLICY_HANDLER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// 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. | ||
|
||
#include "fuchsia/engine/browser/navigation_policy_throttle.h" | ||
|
||
#include "content/public/browser/navigation_handle.h" | ||
#include "fuchsia/engine/browser/navigation_policy_handler.h" | ||
|
||
namespace { | ||
|
||
fuchsia::web::RequestedNavigation ToRequestedNavigation( | ||
content::NavigationHandle* handle, | ||
fuchsia::web::NavigationPhase phase) { | ||
fuchsia::web::RequestedNavigation event; | ||
event.set_id(static_cast<uint64_t>(handle->GetNavigationId())); | ||
event.set_phase(phase); | ||
event.set_is_main_frame(handle->IsInMainFrame()); | ||
event.set_is_same_document(handle->IsSameDocument()); | ||
event.set_is_http_post(handle->IsPost()); | ||
event.set_url(handle->GetURL().spec()); | ||
event.set_has_gesture(handle->HasUserGesture()); | ||
event.set_was_server_redirect(handle->WasServerRedirect()); | ||
|
||
return event; | ||
} | ||
|
||
} // namespace | ||
|
||
NavigationPolicyThrottle::NavigationPolicyThrottle( | ||
content::NavigationHandle* handle, | ||
NavigationPolicyHandler* policy_handler) | ||
: NavigationThrottle(handle), | ||
policy_handler_(policy_handler), | ||
navigation_handle_(handle) { | ||
if (policy_handler->is_provider_connected()) { | ||
policy_handler_->RegisterNavigationThrottle(this); | ||
} else { | ||
policy_handler_ = nullptr; | ||
} | ||
} | ||
|
||
NavigationPolicyThrottle::~NavigationPolicyThrottle() { | ||
if (policy_handler_) | ||
policy_handler_->RemoveNavigationThrottle(this); | ||
} | ||
|
||
void NavigationPolicyThrottle::OnNavigationPolicyProviderDisconnected( | ||
content::NavigationThrottle::ThrottleCheckResult check_result) { | ||
if (is_paused_) { | ||
CancelDeferredNavigation(check_result); | ||
is_paused_ = false; | ||
} | ||
|
||
policy_handler_ = nullptr; | ||
} | ||
|
||
void NavigationPolicyThrottle::OnRequestedNavigationEvaluated( | ||
fuchsia::web::NavigationDecision decision) { | ||
DCHECK(is_paused_); | ||
|
||
switch (decision.Which()) { | ||
case fuchsia::web::NavigationDecision::kProceed: | ||
Resume(); | ||
break; | ||
case fuchsia::web::NavigationDecision::kAbort: | ||
CancelDeferredNavigation(content::NavigationThrottle::CANCEL); | ||
break; | ||
default: | ||
NOTREACHED(); | ||
} | ||
is_paused_ = false; | ||
} | ||
|
||
content::NavigationThrottle::ThrottleCheckResult | ||
NavigationPolicyThrottle::WillStartRequest() { | ||
return HandleNavigationPhase(fuchsia::web::NavigationPhase::START); | ||
} | ||
|
||
content::NavigationThrottle::ThrottleCheckResult | ||
NavigationPolicyThrottle::WillRedirectRequest() { | ||
return HandleNavigationPhase(fuchsia::web::NavigationPhase::REDIRECT); | ||
} | ||
|
||
content::NavigationThrottle::ThrottleCheckResult | ||
NavigationPolicyThrottle::WillFailRequest() { | ||
return HandleNavigationPhase(fuchsia::web::NavigationPhase::FAIL); | ||
} | ||
|
||
content::NavigationThrottle::ThrottleCheckResult | ||
NavigationPolicyThrottle::WillProcessResponse() { | ||
return HandleNavigationPhase(fuchsia::web::NavigationPhase::PROCESS_RESPONSE); | ||
} | ||
|
||
const char* NavigationPolicyThrottle::GetNameForLogging() { | ||
return "NavigationPolicyThrottle"; | ||
} | ||
|
||
content::NavigationThrottle::ThrottleCheckResult | ||
NavigationPolicyThrottle::HandleNavigationPhase( | ||
fuchsia::web::NavigationPhase phase) { | ||
DCHECK(!is_paused_); | ||
|
||
if (!policy_handler_) { | ||
return content::NavigationThrottle::ThrottleCheckResult( | ||
content::NavigationThrottle::CANCEL); | ||
} | ||
|
||
if (!policy_handler_->ShouldEvaluateNavigation(navigation_handle_, phase)) { | ||
return content::NavigationThrottle::ThrottleCheckResult( | ||
content::NavigationThrottle::PROCEED); | ||
} | ||
|
||
policy_handler_->navigation_policy_provider()->EvaluateRequestedNavigation( | ||
ToRequestedNavigation(navigation_handle_, phase), | ||
fit::bind_member( | ||
this, &NavigationPolicyThrottle::OnRequestedNavigationEvaluated)); | ||
|
||
is_paused_ = true; | ||
return content::NavigationThrottle::ThrottleCheckResult( | ||
content::NavigationThrottle::DEFER); | ||
} |
Oops, something went wrong.