blob: 81c59a0ea7df25e6fb26f0fbbb32ebe76de09158 [file] [log] [blame]
// Copyright 2016 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 "third_party/blink/renderer/modules/installedapp/installed_app_controller.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include <utility>
namespace blink {
// Callbacks for the result of
// WebRelatedAppsFetcher::getManifestRelatedApplications. Calls
// filterByInstalledApps upon receiving the list of related applications.
class InstalledAppController::GetRelatedAppsCallbacks
: public AppInstalledCallbacks {
public:
GetRelatedAppsCallbacks(InstalledAppController* controller,
std::unique_ptr<AppInstalledCallbacks> callbacks)
: controller_(controller), callbacks_(std::move(callbacks)) {}
// AppInstalledCallbacks overrides:
void OnSuccess(
const WebVector<WebRelatedApplication>& related_apps) override {
if (!controller_)
return;
controller_->FilterByInstalledApps(related_apps, std::move(callbacks_));
}
void OnError() override { callbacks_->OnError(); }
private:
WeakPersistent<InstalledAppController> controller_;
std::unique_ptr<AppInstalledCallbacks> callbacks_;
};
InstalledAppController::~InstalledAppController() = default;
void InstalledAppController::GetInstalledRelatedApps(
std::unique_ptr<AppInstalledCallbacks> callbacks) {
// When detached, the fetcher is no longer valid.
if (!related_apps_fetcher_) {
// TODO(mgiuca): AbortError rather than simply undefined.
// https://crbug.com/687846
callbacks->OnError();
return;
}
// Get the list of related applications from the manifest. This requires a
// request to the content layer (because the manifest is not a Blink concept).
// Upon returning, filter the result list to those apps that are installed.
// TODO(mgiuca): This roundtrip to content could be eliminated if the Manifest
// class was moved from content into Blink.
related_apps_fetcher_->GetManifestRelatedApplications(
std::make_unique<GetRelatedAppsCallbacks>(this, std::move(callbacks)));
}
void InstalledAppController::ProvideTo(
LocalFrame& frame,
WebRelatedAppsFetcher* related_apps_fetcher) {
Supplement<LocalFrame>::ProvideTo(
frame, new InstalledAppController(frame, related_apps_fetcher));
}
InstalledAppController* InstalledAppController::From(LocalFrame& frame) {
InstalledAppController* controller =
Supplement<LocalFrame>::From<InstalledAppController>(frame);
DCHECK(controller);
return controller;
}
const char InstalledAppController::kSupplementName[] = "InstalledAppController";
InstalledAppController::InstalledAppController(
LocalFrame& frame,
WebRelatedAppsFetcher* related_apps_fetcher)
: Supplement<LocalFrame>(frame),
ContextLifecycleObserver(frame.GetDocument()),
related_apps_fetcher_(related_apps_fetcher) {}
void InstalledAppController::ContextDestroyed(ExecutionContext*) {
provider_.reset();
related_apps_fetcher_ = nullptr;
}
void InstalledAppController::FilterByInstalledApps(
const blink::WebVector<blink::WebRelatedApplication>& related_apps,
std::unique_ptr<blink::AppInstalledCallbacks> callbacks) {
WTF::Vector<mojom::blink::RelatedApplicationPtr> mojo_related_apps;
for (const auto& related_application : related_apps) {
mojom::blink::RelatedApplicationPtr converted_application(
mojom::blink::RelatedApplication::New());
DCHECK(!related_application.platform.IsEmpty());
converted_application->platform = related_application.platform;
converted_application->id = related_application.id;
converted_application->url = related_application.url;
mojo_related_apps.push_back(std::move(converted_application));
}
if (!provider_) {
GetSupplementable()->GetInterfaceProvider().GetInterface(
mojo::MakeRequest(&provider_));
// TODO(mgiuca): Set a connection error handler. This requires a refactor to
// work like NavigatorShare.cpp (retain a persistent list of clients to
// reject all of their promises).
DCHECK(provider_);
}
provider_->FilterInstalledApps(
std::move(mojo_related_apps),
WTF::Bind(&InstalledAppController::OnFilterInstalledApps,
WrapPersistent(this), WTF::Passed(std::move(callbacks))));
}
void InstalledAppController::OnFilterInstalledApps(
std::unique_ptr<blink::AppInstalledCallbacks> callbacks,
WTF::Vector<mojom::blink::RelatedApplicationPtr> result) {
std::vector<blink::WebRelatedApplication> applications;
for (const auto& res : result) {
blink::WebRelatedApplication app;
app.platform = res->platform;
app.url = res->url;
app.id = res->id;
applications.push_back(app);
}
callbacks->OnSuccess(
blink::WebVector<blink::WebRelatedApplication>(applications));
}
void InstalledAppController::Trace(blink::Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
}
} // namespace blink