blob: a809e6bb231be078918db1dc7bd35f4f87f5e302 [file] [log] [blame]
// Copyright 2022 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 "chrome/browser/fuchsia/element_manager_impl.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/ui/browser_list.h"
namespace {
bool HaveBrowser() {
return !BrowserList::GetInstance()->empty();
}
} // namespace
bool ElementManagerImpl::AnnotationKeyCompare::operator()(
const fuchsia::element::AnnotationKey& lhs,
const fuchsia::element::AnnotationKey& rhs) const {
return std::tie(lhs.namespace_, lhs.value) <
std::tie(rhs.namespace_, rhs.value);
}
ElementManagerImpl::ElementManagerImpl(
sys::OutgoingDirectory* outgoing_directory,
NewProposalCallback callback)
: binding_(outgoing_directory, this), callback_(std::move(callback)) {
DCHECK(callback_);
BrowserList::AddObserver(this);
}
ElementManagerImpl::~ElementManagerImpl() {
BrowserList::RemoveObserver(this);
}
std::vector<fuchsia::element::Annotation> ElementManagerImpl::GetAnnotations() {
std::vector<fuchsia::element::Annotation> annotations;
for (const auto& annotation : annotations_) {
annotations.push_back(fidl::Clone(annotation.second));
}
return annotations;
}
void ElementManagerImpl::ProposeElement(
fuchsia::element::Spec spec,
fidl::InterfaceRequest<fuchsia::element::Controller> element_controller,
ProposeElementCallback callback) {
if (spec.component_url() !=
"fuchsia-pkg://fuchsia.com/chrome#meta/chrome.cm") {
callback(fuchsia::element::Manager_ProposeElement_Result::WithErr(
fuchsia::element::ProposeElementError::INVALID_ARGS));
return;
}
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
if (!callback_.Run(command_line)) {
callback(fuchsia::element::Manager_ProposeElement_Result::WithErr(
fuchsia::element::ProposeElementError::INVALID_ARGS));
}
if (element_controller) {
controller_bindings_.AddBinding(this, std::move(element_controller));
}
annotations_.clear();
for (auto& annotation : *spec.mutable_annotations()) {
auto key = fidl::Clone(annotation.key);
annotations_.insert_or_assign(std::move(key), std::move(annotation));
}
callback(fuchsia::element::Manager_ProposeElement_Result::WithResponse({}));
}
void ElementManagerImpl::UpdateAnnotations(
std::vector<fuchsia::element::Annotation> annotations_to_set,
std::vector<fuchsia::element::AnnotationKey> annotations_to_delete,
UpdateAnnotationsCallback callback) {
for (const auto& key : annotations_to_delete) {
annotations_.erase(key);
}
for (auto& annotation : annotations_to_set) {
auto key = fidl::Clone(annotation.key);
annotations_.insert_or_assign(std::move(key), std::move(annotation));
}
callback(fuchsia::element::AnnotationController_UpdateAnnotations_Result::
WithResponse({}));
}
void ElementManagerImpl::GetAnnotations(GetAnnotationsCallback callback) {
fuchsia::element::AnnotationController_GetAnnotations_Response response(
GetAnnotations());
callback(fuchsia::element::AnnotationController_GetAnnotations_Result::
WithResponse(std::move(response)));
}
void ElementManagerImpl::OnBrowserRemoved(Browser* browser) {
// If the browser was the last, clear all active bindings to notify the shell.
bool have_browser =
have_browser_for_test_ ? have_browser_for_test_.Run() : HaveBrowser();
if (!have_browser) {
controller_bindings_.CloseAll();
}
}