blob: f9a40fa76b91ef0fcefbb5feb90dd7f8ca2952eb [file] [log] [blame]
// Copyright 2019 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 "src/sys/appmgr/log_connector_impl.h"
#include <lib/async/cpp/task.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/syslog/global.h>
#include "src/lib/fsl/handles/object_info.h"
#include "src/sys/appmgr/util.h"
namespace component {
LogConnectorImpl::LogConnectorImpl(fxl::WeakPtr<LogConnectorImpl> parent, std::string realm_label)
: parent_(std::move(parent)),
realm_label_(realm_label),
consumer_request_(consumer_.NewRequest()),
weak_factory_(this) {}
LogConnectorImpl::LogConnectorImpl(std::string realm_label)
: LogConnectorImpl(nullptr /* parent */, realm_label) {}
fbl::RefPtr<LogConnectorImpl> LogConnectorImpl::NewChild(std::string child_realm_label) {
auto child = new LogConnectorImpl(weak_factory_.GetWeakPtr(), child_realm_label);
return AdoptRef(child);
}
void LogConnectorImpl::TakeLogConnectionListener(TakeLogConnectionListenerCallback callback) {
FX_LOGS(INFO) << "taking log connector for " << realm_label_;
callback(std::move(consumer_request_));
// This once-callback will be set only for the root "app" realm and it will be
// available because it is set before we run the event loop.
if (on_ready_) {
(*on_ready_)();
on_ready_.reset();
}
}
void LogConnectorImpl::OnReady(fit::function<void()> on_ready) { on_ready_ = std::move(on_ready); }
void LogConnectorImpl::AddConnectorClient(
fidl::InterfaceRequest<fuchsia::sys::internal::LogConnector> request) {
bindings_.AddBinding(this, std::move(request));
}
void LogConnectorImpl::AddLogConnection(
std::string component_url, std::string instance_id,
fidl::InterfaceRequest<fuchsia::logger::LogSink> connection) {
// find the nearest initialized LogConnector, assumes that >=1 one is instantiated before this
std::vector<std::string> realm_path;
auto current = this;
while (current->parent_ && current->consumer_request_.is_valid()) {
realm_path.push_back(current->realm_label_);
current = &*current->parent_;
}
std::reverse(realm_path.begin(), realm_path.end());
// Align log identity realm paths with event realm paths. In other words, strip the "sys"
// realm name if we are referring to a component under the root sys realm (not a test one).
if (realm_path.size() > 0 && realm_path[0].compare("sys") == 0 && current &&
current->realm_label_.compare("app") == 0) {
realm_path.erase(realm_path.begin());
}
auto component_name = Util::GetLabelFromURL(component_url);
fuchsia::sys::internal::SourceIdentity identity;
identity.set_instance_id(instance_id);
identity.set_realm_path(realm_path);
identity.set_component_url(std::move(component_url));
identity.set_component_name(std::move(component_name));
current->consumer_->OnNewConnection({
.log_request = std::move(connection),
.source_identity = std::move(identity),
});
}
} // namespace component