blob: 8b687d1070deac481de50738e12615e10a8e0fc6 [file] [log] [blame]
// Copyright 2016 The Fuchsia 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 <array>
#include <memory>
#include <fuchsia/cpp/modular.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include "lib/app/cpp/application_context.h"
#include "lib/app_driver/cpp/app_driver.h"
#include "lib/fsl/tasks/message_loop.h"
#include "lib/ui/view_framework/base_view.h"
#include "peridot/lib/fidl/single_service_app.h"
namespace {
constexpr uint32_t kChildKey = 1;
constexpr int kSwapSeconds = 5;
constexpr std::array<const char*, 2> kModuleQueries{
{"swap_module1", "swap_module2"}};
class RecipeView : public mozart::BaseView {
public:
explicit RecipeView(
views_v1::ViewManagerPtr view_manager,
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner_request)
: BaseView(std::move(view_manager),
std::move(view_owner_request),
"RecipeView") {}
~RecipeView() override = default;
void SetChild(views_v1_token::ViewOwnerPtr view_owner) {
if (host_node_) {
GetViewContainer()->RemoveChild(kChildKey, nullptr);
host_node_->Detach();
host_node_.reset();
}
if (view_owner) {
host_node_ = std::make_unique<scenic_lib::EntityNode>(session());
zx::eventpair host_import_token;
host_node_->ExportAsRequest(&host_import_token);
parent_node().AddChild(*host_node_);
GetViewContainer()->AddChild(kChildKey, std::move(view_owner),
std::move(host_import_token));
}
}
private:
// |BaseView|:
void OnPropertiesChanged(views_v1::ViewProperties) override {
if (host_node_) {
auto child_properties = views_v1::ViewProperties::New();
fidl::Clone(properties(), child_properties.get());
GetViewContainer()->SetChildProperties(kChildKey,
std::move(child_properties));
}
}
std::unique_ptr<scenic_lib::EntityNode> host_node_;
};
class RecipeApp : public modular::SingleServiceApp<modular::Module> {
public:
RecipeApp(component::ApplicationContext* const application_context)
: SingleServiceApp(application_context) {}
~RecipeApp() override = default;
private:
// |SingleServiceApp|
void CreateView(
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner_request,
fidl::InterfaceRequest<component::ServiceProvider> /*services*/)
override {
view_ = std::make_unique<RecipeView>(
application_context()
->ConnectToEnvironmentService<views_v1::ViewManager>(),
std::move(view_owner_request));
SetChild();
}
// |Module|
void Initialize(
fidl::InterfaceHandle<modular::ModuleContext> module_context,
fidl::InterfaceRequest<component::ServiceProvider> /*outgoing_services*/)
override {
module_context_.Bind(std::move(module_context));
SwapModule();
}
void SwapModule() {
StartModule(kModuleQueries[query_index_]);
query_index_ = (query_index_ + 1) % kModuleQueries.size();
async::PostDelayedTask(async_get_default(),
[this] { SwapModule(); },
zx::sec(kSwapSeconds));
}
void StartModule(const std::string& module_query) {
if (module_) {
module_->Stop([this, module_query] {
module_.Unbind();
module_view_.Unbind();
StartModule(module_query);
});
return;
}
// This module is named after its URL.
modular::Daisy daisy;
daisy.url = module_query;
module_context_->EmbedModule(
module_query, std::move(daisy), nullptr, module_.NewRequest(),
module_view_.NewRequest(), [](const modular::StartModuleStatus&) {});
SetChild();
}
void SetChild() {
if (view_ && module_view_) {
view_->SetChild(std::move(module_view_));
}
}
modular::ModuleContextPtr module_context_;
modular::ModuleControllerPtr module_;
views_v1_token::ViewOwnerPtr module_view_;
std::unique_ptr<RecipeView> view_;
int query_index_ = 0;
};
} // namespace
int main(int /*argc*/, const char** /*argv*/) {
fsl::MessageLoop loop;
auto app_context = component::ApplicationContext::CreateFromStartupInfo();
modular::AppDriver<RecipeApp> driver(
app_context->outgoing_services(),
std::make_unique<RecipeApp>(app_context.get()),
[&loop] { loop.QuitNow(); });
loop.Run();
return 0;
}