blob: 126148dea907d85f7ccc7df2653ee2aea0f2dfc9 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/manifest/manifest_manager_host.h"
#include <stdint.h>
#include "base/bind.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/common/content_client.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
#include "url/gurl.h"
namespace content {
ManifestManagerHost::ManifestManagerHost(Page& page)
: PageUserData<ManifestManagerHost>(page) {}
ManifestManagerHost::~ManifestManagerHost() {
DispatchPendingCallbacks();
}
void ManifestManagerHost::BindObserver(
mojo::PendingAssociatedReceiver<blink::mojom::ManifestUrlChangeObserver>
receiver) {
manifest_url_change_observer_receiver_.Bind(std::move(receiver));
manifest_url_change_observer_receiver_.SetFilter(
static_cast<RenderFrameHostImpl&>(page().GetMainDocument())
.CreateMessageFilterForAssociatedReceiver(
blink::mojom::ManifestUrlChangeObserver::Name_));
}
void ManifestManagerHost::GetManifest(GetManifestCallback callback) {
// Do not call into MaybeOverrideManifest in a non primary page since
// it checks the url from PreRedirectionURLObserver that works only in
// a primary page.
// TODO(crbug.com/1296125): Maybe cancel prerendering if it hits this.
if (!page().IsPrimary()) {
std::move(callback).Run(GURL(), blink::mojom::Manifest::New());
return;
}
auto& manifest_manager = GetManifestManager();
int request_id = callbacks_.Add(
std::make_unique<GetManifestCallback>(std::move(callback)));
manifest_manager.RequestManifest(
base::BindOnce(&ManifestManagerHost::OnRequestManifestResponse,
base::Unretained(this), request_id));
}
void ManifestManagerHost::RequestManifestDebugInfo(
blink::mojom::ManifestManager::RequestManifestDebugInfoCallback callback) {
GetManifestManager().RequestManifestDebugInfo(std::move(callback));
}
blink::mojom::ManifestManager& ManifestManagerHost::GetManifestManager() {
if (!manifest_manager_) {
page().GetMainDocument().GetRemoteInterfaces()->GetInterface(
manifest_manager_.BindNewPipeAndPassReceiver());
manifest_manager_.set_disconnect_handler(base::BindOnce(
&ManifestManagerHost::OnConnectionError, base::Unretained(this)));
}
return *manifest_manager_;
}
void ManifestManagerHost::DispatchPendingCallbacks() {
std::vector<GetManifestCallback> callbacks;
for (CallbackMap::iterator it(&callbacks_); !it.IsAtEnd(); it.Advance()) {
callbacks.push_back(std::move(*it.GetCurrentValue()));
}
callbacks_.Clear();
for (auto& callback : callbacks)
std::move(callback).Run(GURL(), blink::mojom::Manifest::New());
}
void ManifestManagerHost::OnConnectionError() {
DispatchPendingCallbacks();
if (GetForPage(page()))
DeleteForPage(page());
}
void ManifestManagerHost::OnRequestManifestResponse(
int request_id,
const GURL& url,
blink::mojom::ManifestPtr manifest) {
GetContentClient()->browser()->MaybeOverrideManifest(
&page().GetMainDocument(), manifest);
auto callback = std::move(*callbacks_.Lookup(request_id));
callbacks_.Remove(request_id);
std::move(callback).Run(url, std::move(manifest));
}
void ManifestManagerHost::ManifestUrlChanged(const GURL& manifest_url) {
static_cast<PageImpl&>(page()).UpdateManifestUrl(manifest_url);
}
PAGE_USER_DATA_KEY_IMPL(ManifestManagerHost);
} // namespace content