blob: e59e75b6555a80028073676a16433004a8825b33 [file] [log] [blame]
// Copyright 2017 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.
#ifndef PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_
#define PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_
#include <functional>
#include <memory>
#include <set>
#include <vector>
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/async/cpp/operation.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fxl/memory/weak_ptr.h>
#include "peridot/lib/module_manifest_source/module_manifest_source.h"
namespace modular {
class LocalModuleResolver : fuchsia::modular::ModuleResolver,
fuchsia::modular::QueryHandler {
public:
LocalModuleResolver();
~LocalModuleResolver() override;
// Adds a source of Module manifests to index. It is not allowed to call
// AddSource() after Connect(). |name| must be unique.
void AddSource(std::string name, std::unique_ptr<ModuleManifestSource> repo);
void Connect(
fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request);
void BindQueryHandler(
fidl::InterfaceRequest<fuchsia::modular::QueryHandler> request);
// |ModuleResolver|
void FindModules(fuchsia::modular::FindModulesQuery query,
FindModulesCallback callback) override;
// |ModuleResolver|
void FindModulesByTypes(fuchsia::modular::FindModulesByTypesQuery query,
FindModulesByTypesCallback callback) override;
// |ModuleResolver|
void GetModuleManifest(std::string module_id,
GetModuleManifestCallback callback) override;
private:
class FindModulesCall;
class FindModulesByTypesCall;
using ModuleUri = std::string;
using RepoSource = std::string;
// We use the module URI to identify the module manifest.
using ManifestId = std::tuple<RepoSource, ModuleUri>;
using ParameterName = std::string;
using ParameterType = std::string;
using Action = std::string;
std::set<ManifestId> FindHandlers(ModuleUri handler);
// |fuchsia::modular::QueryHandler|
void OnQuery(fuchsia::modular::UserInput query,
OnQueryCallback done) override;
void OnSourceIdle(const std::string& source_name);
void OnNewManifestEntry(const std::string& source_name, std::string id_in,
fuchsia::modular::ModuleManifest new_entry);
void OnRemoveManifestEntry(const std::string& source_name, std::string id_in);
void PeriodicCheckIfSourcesAreReady();
bool AllSourcesAreReady() const {
return ready_sources_.size() == sources_.size();
}
// TODO(thatguy): At some point, factor the index functions out of
// LocalModuleResolver so that they can be re-used by the general all-modules
// Ask handler.
std::map<std::string, std::unique_ptr<ModuleManifestSource>> sources_;
// Set of sources that have told us they are idle, meaning they have
// sent us all manifests they knew about at construction time.
std::set<std::string> ready_sources_;
// Map of module manifest ID -> module manifest.
using ManifestMap = std::map<ManifestId, fuchsia::modular::ModuleManifest>;
ManifestMap manifests_;
// action -> key in |manifests_|
std::map<Action, std::set<ManifestId>> action_to_manifests_;
// (parameter type, parameter name) -> key in |manifests_|
std::map<std::pair<ParameterType, ParameterName>, std::set<ManifestId>>
parameter_type_and_name_to_manifests_;
// (parameter type) -> keys in |manifests_|.
std::map<ParameterType, std::set<ManifestId>> parameter_type_to_manifests_;
fidl::BindingSet<fuchsia::modular::ModuleResolver> bindings_;
fidl::Binding<fuchsia::modular::QueryHandler> query_handler_binding_;
// These are buffered until AllSourcesAreReady() == true.
std::vector<fidl::InterfaceRequest<fuchsia::modular::ModuleResolver>>
pending_bindings_;
bool already_checking_if_sources_are_ready_;
OperationCollection operations_;
fxl::WeakPtrFactory<LocalModuleResolver> weak_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(LocalModuleResolver);
};
} // namespace modular
#endif // PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_