Commit ac540b1e authored by Kurt Horimoto's avatar Kurt Horimoto Committed by Commit Bot

[iOS] Create OverlayRequestQueueCallbackInstaller

This is a helper object that installs callbacks for every request that
is added to an OverlayRequestQueue.  It uses OverlayRequestQueueImpl::
Observer to detect newly-added requests, and installs callbacks on each
added request using a list of OverlayRequestCallbackInstallers.

This CL also updates OverlayRequestQueueImpl::Observer to include
OverlayRequestQueueDestroyed().  This was not necessary before
since the only queue observer was OverlayPresenterImpl, which is
Browser-scoped and guaranteed to outlive all WebState-scoped queues.
No such guarantee is made by OverlayRequestQueueCallbackInstaller, so
a destruction observer callback is used to stop observation.

Additionally, OverlayRequestQueueImpl::FromWebState() was added in order
to safely fetch an OverlayRequestQueueImpl from the queue callback
installer in order to observe the queues.

Bug: 1030357
Change-Id: Ie1769b593f637a29dae9efe13de5e4d7d5a58164
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2032680
Commit-Queue: Kurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarMike Dougherty <michaeldo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737880}
parent a1886ef5
...@@ -20,6 +20,7 @@ source_set("overlays") { ...@@ -20,6 +20,7 @@ source_set("overlays") {
"public/overlay_request_cancel_handler.h", "public/overlay_request_cancel_handler.h",
"public/overlay_request_config.h", "public/overlay_request_config.h",
"public/overlay_request_queue.h", "public/overlay_request_queue.h",
"public/overlay_request_queue_callback_installer.h",
"public/overlay_request_support.h", "public/overlay_request_support.h",
"public/overlay_response.h", "public/overlay_response.h",
"public/overlay_response_info.h", "public/overlay_response_info.h",
...@@ -41,6 +42,8 @@ source_set("overlays") { ...@@ -41,6 +42,8 @@ source_set("overlays") {
"overlay_request_cancel_handler.mm", "overlay_request_cancel_handler.mm",
"overlay_request_impl.cc", "overlay_request_impl.cc",
"overlay_request_impl.h", "overlay_request_impl.h",
"overlay_request_queue_callback_installer_impl.h",
"overlay_request_queue_callback_installer_impl.mm",
"overlay_request_queue_impl.h", "overlay_request_queue_impl.h",
"overlay_request_queue_impl.mm", "overlay_request_queue_impl.mm",
"overlay_request_support.cc", "overlay_request_support.cc",
...@@ -72,6 +75,7 @@ source_set("unit_tests") { ...@@ -72,6 +75,7 @@ source_set("unit_tests") {
"overlay_presenter_observer_bridge_unittest.mm", "overlay_presenter_observer_bridge_unittest.mm",
"overlay_request_callback_installer_unittest.cc", "overlay_request_callback_installer_unittest.cc",
"overlay_request_impl_unittest.cc", "overlay_request_impl_unittest.cc",
"overlay_request_queue_callback_installer_unittest.mm",
"overlay_request_queue_impl_unittest.mm", "overlay_request_queue_impl_unittest.mm",
"overlay_request_support_unittest.cc", "overlay_request_support_unittest.cc",
"overlay_request_unittest.cc", "overlay_request_unittest.cc",
......
...@@ -112,6 +112,7 @@ class OverlayPresenterImpl : public BrowserObserver, ...@@ -112,6 +112,7 @@ class OverlayPresenterImpl : public BrowserObserver,
size_t index) override; size_t index) override;
void QueuedRequestCancelled(OverlayRequestQueueImpl* queue, void QueuedRequestCancelled(OverlayRequestQueueImpl* queue,
OverlayRequest* request) override; OverlayRequest* request) override;
void OverlayRequestQueueDestroyed(OverlayRequestQueueImpl* queue) override;
// OverlayPresentationContextObserver: // OverlayPresentationContextObserver:
void OverlayPresentationContextWillChangePresentationCapabilities( void OverlayPresentationContextWillChangePresentationCapabilities(
......
...@@ -356,6 +356,11 @@ void OverlayPresenterImpl::QueuedRequestCancelled( ...@@ -356,6 +356,11 @@ void OverlayPresenterImpl::QueuedRequestCancelled(
CancelOverlayUIForRequest(request); CancelOverlayUIForRequest(request);
} }
void OverlayPresenterImpl::OverlayRequestQueueDestroyed(
OverlayRequestQueueImpl* queue) {
queue->RemoveObserver(this);
}
#pragma mark - OverlayPresentationContextObserver #pragma mark - OverlayPresentationContextObserver
void OverlayPresenterImpl:: void OverlayPresenterImpl::
......
// 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 IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_IMPL_H_
#define IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_IMPL_H_
#include <vector>
#import "ios/chrome/browser/overlays/public/overlay_request_queue_callback_installer.h"
#include "base/scoped_observer.h"
#import "ios/chrome/browser/overlays/overlay_request_queue_impl.h"
class OverlayRequestQueueCallbackInstallerImpl
: public OverlayRequestQueueCallbackInstaller {
public:
OverlayRequestQueueCallbackInstallerImpl(web::WebState* web_state,
OverlayModality modality);
~OverlayRequestQueueCallbackInstallerImpl() override;
private:
// Observer that installs callbacks for each request added to a queue.
class RequestAddedObserver : public OverlayRequestQueueImpl::Observer {
public:
RequestAddedObserver(web::WebState* web_state, OverlayModality modality);
~RequestAddedObserver() override;
// Adds |installer| to be executed for every request added to the queue.
void AddInstaller(
std::unique_ptr<OverlayRequestCallbackInstaller> installer);
private:
// OverlayRequestQueueImpl::Observer:
void RequestAddedToQueue(OverlayRequestQueueImpl* queue,
OverlayRequest* request,
size_t index) override;
void OverlayRequestQueueDestroyed(OverlayRequestQueueImpl* queue) override;
// The installers for the queue.
std::vector<std::unique_ptr<OverlayRequestCallbackInstaller>> installers_;
ScopedObserver<OverlayRequestQueueImpl, OverlayRequestQueueImpl::Observer>
scoped_observer_;
};
// OverlayRequestQueueCallbackInstaller:
void AddRequestCallbackInstaller(
std::unique_ptr<OverlayRequestCallbackInstaller> installer) override;
// The observer responsible for installing callbacks for each OverlayRequest
// added to a queue.
RequestAddedObserver request_added_observer_;
};
#endif // IOS_CHROME_BROWSER_OVERLAYS_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_IMPL_H_
// 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.
#import "ios/chrome/browser/overlays/overlay_request_queue_callback_installer_impl.h"
#include "base/logging.h"
#include "ios/chrome/browser/overlays/public/overlay_request_callback_installer.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#pragma mark - OverlayRequestQueueCallbackInstaller
// static
std::unique_ptr<OverlayRequestQueueCallbackInstaller>
OverlayRequestQueueCallbackInstaller::Create(web::WebState* web_state,
OverlayModality modality) {
return std::make_unique<OverlayRequestQueueCallbackInstallerImpl>(web_state,
modality);
}
#pragma mark - OverlayRequestQueueCallbackInstallerImpl
OverlayRequestQueueCallbackInstallerImpl::
OverlayRequestQueueCallbackInstallerImpl(web::WebState* web_state,
OverlayModality modality)
: request_added_observer_(web_state, modality) {}
OverlayRequestQueueCallbackInstallerImpl::
~OverlayRequestQueueCallbackInstallerImpl() = default;
#pragma mark OverlayRequestQueueCallbackInstaller
void OverlayRequestQueueCallbackInstallerImpl::AddRequestCallbackInstaller(
std::unique_ptr<OverlayRequestCallbackInstaller> installer) {
request_added_observer_.AddInstaller(std::move(installer));
}
#pragma mark - OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver
OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver::
RequestAddedObserver(web::WebState* web_state, OverlayModality modality)
: scoped_observer_(this) {
DCHECK(web_state);
scoped_observer_.Add(
OverlayRequestQueueImpl::FromWebState(web_state, modality));
}
OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver::
~RequestAddedObserver() = default;
#pragma mark Public
void OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver::
AddInstaller(std::unique_ptr<OverlayRequestCallbackInstaller> installer) {
DCHECK(installer);
installers_.push_back(std::move(installer));
}
#pragma mark OverlayRequestQueueImpl::Observer
void OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver::
RequestAddedToQueue(OverlayRequestQueueImpl* queue,
OverlayRequest* request,
size_t index) {
for (auto& installer : installers_) {
installer->InstallCallbacks(request);
}
}
void OverlayRequestQueueCallbackInstallerImpl::RequestAddedObserver::
OverlayRequestQueueDestroyed(OverlayRequestQueueImpl* queue) {
scoped_observer_.Remove(queue);
}
// 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.
#import "ios/chrome/browser/overlays/public/overlay_request_queue_callback_installer.h"
#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
#import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
#include "ios/chrome/browser/overlays/test/fake_overlay_request_callback_installer.h"
#include "ios/chrome/browser/overlays/test/overlay_test_macros.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// OverlayModality used in tests.
const OverlayModality kModality = OverlayModality::kWebContentArea;
// OverlayRequest ConfigType used for testing.
DEFINE_TEST_OVERLAY_REQUEST_CONFIG(SupportedConfig);
// OverlayResponse InfoType used for testing.
DEFINE_TEST_OVERLAY_RESPONSE_INFO(DispatchInfo);
} // namespace
// Test fixture for OverlayRequestQueueCallbackInstaller.
class OverlayRequestQueueCallbackInstallerTest : public PlatformTest {
public:
OverlayRequestQueueCallbackInstallerTest()
: queue_installer_(
OverlayRequestQueueCallbackInstaller::Create(&web_state_,
kModality)) {
std::unique_ptr<FakeOverlayRequestCallbackInstaller> request_installer =
std::make_unique<FakeOverlayRequestCallbackInstaller>(
&callback_receiver_, std::set<const OverlayResponseSupport*>(
{DispatchInfo::ResponseSupport()}));
request_installer->set_request_support(SupportedConfig::RequestSupport());
queue_installer_->AddRequestCallbackInstaller(std::move(request_installer));
}
~OverlayRequestQueueCallbackInstallerTest() = default;
OverlayRequestQueue* queue() {
return OverlayRequestQueue::FromWebState(&web_state_, kModality);
}
protected:
web::TestWebState web_state_;
testing::StrictMock<MockOverlayRequestCallbackReceiver> callback_receiver_;
std::unique_ptr<OverlayRequestQueueCallbackInstaller> queue_installer_;
};
// Tests that callbacks are installed for supported requests added to the queue.
TEST_F(OverlayRequestQueueCallbackInstallerTest, InstallForSupportedRequest) {
std::unique_ptr<OverlayRequest> added_request =
OverlayRequest::CreateWithConfig<SupportedConfig>();
OverlayRequest* request = added_request.get();
queue()->AddRequest(std::move(added_request));
// Dispatch a response through |request|, expecting the dispatch callback to
// be executed on the mock receiver.
EXPECT_CALL(callback_receiver_,
DispatchCallback(request, DispatchInfo::ResponseSupport()));
request->GetCallbackManager()->DispatchResponse(
OverlayResponse::CreateWithInfo<DispatchInfo>());
// Cancel the requests, expecting the completion callback to be executed on
// the mock receiver.
EXPECT_CALL(callback_receiver_, CompletionCallback(request));
queue()->CancelAllRequests();
}
...@@ -53,8 +53,15 @@ class OverlayRequestQueueImpl : public OverlayRequestQueue { ...@@ -53,8 +53,15 @@ class OverlayRequestQueueImpl : public OverlayRequestQueue {
// All requests in a queue are cancelled before the queue is destroyed. // All requests in a queue are cancelled before the queue is destroyed.
virtual void QueuedRequestCancelled(OverlayRequestQueueImpl* queue, virtual void QueuedRequestCancelled(OverlayRequestQueueImpl* queue,
OverlayRequest* request) {} OverlayRequest* request) {}
// Called when |queue| is about to be destroyed.
virtual void OverlayRequestQueueDestroyed(OverlayRequestQueueImpl* queue) {}
}; };
// Returns the request queue implementation for |web_state| at |modality|.
static OverlayRequestQueueImpl* FromWebState(web::WebState* web_state,
OverlayModality modality);
// Adds and removes observers. // Adds and removes observers.
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
......
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
OverlayRequestQueue* OverlayRequestQueue::FromWebState( OverlayRequestQueue* OverlayRequestQueue::FromWebState(
web::WebState* web_state, web::WebState* web_state,
OverlayModality modality) { OverlayModality modality) {
OverlayRequestQueueImpl::Container::CreateForWebState(web_state); return OverlayRequestQueueImpl::FromWebState(web_state, modality);
return OverlayRequestQueueImpl::Container::FromWebState(web_state)
->QueueForModality(modality);
} }
#pragma mark - OverlayRequestQueueImpl::Container #pragma mark - OverlayRequestQueueImpl::Container
...@@ -45,9 +43,22 @@ OverlayRequestQueueImpl* OverlayRequestQueueImpl::Container::QueueForModality( ...@@ -45,9 +43,22 @@ OverlayRequestQueueImpl* OverlayRequestQueueImpl::Container::QueueForModality(
#pragma mark - OverlayRequestQueueImpl #pragma mark - OverlayRequestQueueImpl
OverlayRequestQueueImpl* OverlayRequestQueueImpl::FromWebState(
web::WebState* web_state,
OverlayModality modality) {
OverlayRequestQueueImpl::Container::CreateForWebState(web_state);
return OverlayRequestQueueImpl::Container::FromWebState(web_state)
->QueueForModality(modality);
}
OverlayRequestQueueImpl::OverlayRequestQueueImpl(web::WebState* web_state) OverlayRequestQueueImpl::OverlayRequestQueueImpl(web::WebState* web_state)
: web_state_(web_state), weak_factory_(this) {} : web_state_(web_state), weak_factory_(this) {}
OverlayRequestQueueImpl::~OverlayRequestQueueImpl() = default;
OverlayRequestQueueImpl::~OverlayRequestQueueImpl() {
for (auto& observer : observers_) {
observer.OverlayRequestQueueDestroyed(this);
}
}
#pragma mark Public #pragma mark Public
......
// 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 IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_H_
#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_H_
#include <memory>
#include "ios/chrome/browser/overlays/public/overlay_modality.h"
class OverlayRequestCallbackInstaller;
namespace web {
class WebState;
}
// Helper object that installs callbacks on every OverlayRequest added to the
// OverlayRequestQueue for a given Browser and OverlayModality.
class OverlayRequestQueueCallbackInstaller {
public:
// Creates an installer for requests in |web_state|'s queue at |modality|.
static std::unique_ptr<OverlayRequestQueueCallbackInstaller> Create(
web::WebState* web_state,
OverlayModality modality);
OverlayRequestQueueCallbackInstaller(
const OverlayRequestQueueCallbackInstaller&) = delete;
OverlayRequestQueueCallbackInstaller& operator=(
const OverlayRequestQueueCallbackInstaller&) = delete;
virtual ~OverlayRequestQueueCallbackInstaller() = default;
// Adds a callback installer for requests added to the WebState's queue.
// InstallCallbacks() will be called on every added request callback installer
// for every OverlayRequest added to the queue.
virtual void AddRequestCallbackInstaller(
std::unique_ptr<OverlayRequestCallbackInstaller> installer) = 0;
protected:
// OverlayRequestQueueCallbackInstallers must be created using factory method.
OverlayRequestQueueCallbackInstaller() = default;
};
#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_REQUEST_QUEUE_CALLBACK_INSTALLER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment