blob: 2cbc6a4c6f568be0201a51dfef684c4dbfbd21dc [file] [log] [blame]
// Copyright 2022 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 SRC_DEVELOPER_ADB_BIN_ADB_SHELL_ADB_SHELL_H_
#define SRC_DEVELOPER_ADB_BIN_ADB_SHELL_ADB_SHELL_H_
#include <fidl/fuchsia.dash/cpp/wire.h>
#include <fidl/fuchsia.hardware.adb/cpp/wire.h>
#include <optional>
#include <string>
#include <fbl/auto_lock.h>
#include "src/developer/adb/bin/adb-shell/adb_shell_config.h"
namespace adb_shell {
class AdbShellImpl;
// Provides shell service to adb daemon.
class AdbShell : public fidl::WireServer<fuchsia_hardware_adb::Provider> {
public:
explicit AdbShell(fidl::ClientEnd<fuchsia_io::Directory> svc, async_dispatcher_t* dispatcher,
adb_shell_config::Config config)
: svc_(std::move(svc)), dispatcher_(dispatcher), config_(std::move(config)) {}
// fuchsia_hardware_adb::Provider methods.
void ConnectToService(ConnectToServiceRequestView request,
ConnectToServiceCompleter::Sync& completer) override;
// For testing, return the current shell instance count.
size_t ActiveShellInstances() {
fbl::AutoLock _(&shell_lock_);
return shells_.size();
}
// Create a new shell instance to service an incoming connect request.
zx_status_t AddShell(std::optional<std::string> args, zx::socket client);
private:
// Destroy shell instance.
void RemoveShell(AdbShellImpl* shell);
fbl::Mutex shell_lock_;
std::vector<std::unique_ptr<AdbShellImpl>> shells_ __TA_GUARDED(shell_lock_);
fidl::ClientEnd<fuchsia_io::Directory> svc_;
async_dispatcher_t* dispatcher_;
adb_shell_config::Config config_;
};
// Class containing context of each shell instance.
class AdbShellImpl : public fidl::WireAsyncEventHandler<fuchsia_dash::Launcher> {
public:
explicit AdbShellImpl(fidl::UnownedClientEnd<fuchsia_io::Directory> svc,
async_dispatcher_t* dispatcher)
: svc_(svc), dispatcher_(dispatcher) {}
// Starts a dash shell with the help of dash launcher service. |moniker| is configured during
// build time and is "./bootstrap/console-launcher" by default which provides a shell similar to
// serial console. When the |adb| socket closes or when the user exits the shell, the dash
// launcher will terminate the dash instance and sends an OnTerminate event which will eventually
// result in dtor of AdbShellImpl getting called.
zx_status_t Start(zx::socket adb, std::string moniker, std::optional<std::string> args,
fit::callback<void(AdbShellImpl*)> on_dead);
// fuchsia_dash::Launcher event.
void OnTerminated(fidl::WireEvent<fuchsia_dash::Launcher::OnTerminated>* event) override;
private:
// Resolve component moniker so that it is in the right state to shell into it.
zx_status_t ResolveMoniker(std::string moniker);
fit::callback<void(AdbShellImpl*)> on_dead_ = [](auto adb_shell) {};
fidl::UnownedClientEnd<fuchsia_io::Directory> svc_;
fidl::WireSharedClient<fuchsia_dash::Launcher> dash_client_;
async_dispatcher_t* dispatcher_;
};
} // namespace adb_shell
#endif // SRC_DEVELOPER_ADB_BIN_ADB_SHELL_ADB_SHELL_H_