blob: a5927b53acfc6297f41bedd70e3d6f04bc33d77a [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 "arc/data-snapshotd/block_ui_controller.h"
#include <stdlib.h>
#include <utility>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/process/launch.h>
#include <base/time/time.h>
#include <brillo/process/process.h>
namespace arc {
namespace data_snapshotd {
namespace {
constexpr base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(20);
constexpr char kDisplayBinary[] = "chromeos-boot-alert";
// Environment variables and values:
constexpr char kMessageOptions[] = "MESSAGE_OPTIONS";
constexpr char kMarkup[] = "--markup";
constexpr char kTmpDir[] = "TMPDIR";
constexpr char kTmpDirValue[] = "/var/cache/arc-data-snapshot/tmp/";
constexpr char kImageBackgroundRgb[] = "IMAGE_BACKGROUND_RGB";
constexpr char kImageBackgroundRgbValue[] = "fefefe";
constexpr char kImageTextColor[] = "IMAGE_TEXT_COLOR";
constexpr char kImageTextColorValue[] = "Black";
constexpr char kAssetsImagePath[] = "ASSETS_IMAGE_PATH";
constexpr char kAssetsImagePathValue[] = "images";
constexpr char kProgressBarWidth[] = "PROGRESS_BAR_WIDTH";
constexpr char kProgressBarWidthValue[] = "1";
constexpr char kProgressBarRgb[] = "PROGRESS_BAR_RGB";
constexpr char kProgressBarRgbValue[] = "1A73E8";
bool LaunchProcessImpl(const base::CommandLine& cmd,
const base::LaunchOptions& options) {
int exit_code;
auto p = base::LaunchProcess(cmd, options);
if (!p.WaitForExitWithTimeout(kTimeout, &exit_code) ||
exit_code != EXIT_SUCCESS) {
return false;
}
return true;
}
} // namespace
base::CommandLine GetShowScreenCommandLine() {
base::CommandLine cmd{base::FilePath(kDisplayBinary)};
cmd.AppendArg("update_arc_data_snapshot");
return cmd;
}
base::CommandLine GetUpdateProgressCommandLine(int percent) {
base::CommandLine cmd{base::FilePath(kDisplayBinary)};
cmd.AppendArg("update_progress");
cmd.AppendArg(std::to_string(percent));
return cmd;
}
base::LaunchOptions GetShowScreenOptions(const base::FilePath& snapshot_dir) {
base::EnvironmentMap env;
env[kMessageOptions] = kMarkup;
env[kTmpDir] = kTmpDirValue;
env[kAssetsImagePath] = snapshot_dir.Append(kAssetsImagePathValue).value();
env[kImageBackgroundRgb] = kImageBackgroundRgbValue;
env[kImageTextColor] = kImageTextColorValue;
base::LaunchOptions options;
options.environment = std::move(env);
return options;
}
base::LaunchOptions GetUpdateProgressOptions() {
base::EnvironmentMap env;
env[kProgressBarWidth] = kProgressBarWidthValue;
env[kProgressBarRgb] = kProgressBarRgbValue;
env[kImageBackgroundRgb] = kImageBackgroundRgbValue;
base::LaunchOptions options;
options.environment = std::move(env);
return options;
}
BlockUiController::BlockUiController(std::unique_ptr<EscKeyWatcher> watcher,
const base::FilePath& snapshot_dir)
: BlockUiController(std::move(watcher),
snapshot_dir,
base::BindRepeating(&LaunchProcessImpl)) {}
BlockUiController::~BlockUiController() {}
// static
std::unique_ptr<BlockUiController> BlockUiController::CreateForTesting(
std::unique_ptr<EscKeyWatcher> watcher,
const base::FilePath& snapshot_dir,
LaunchProcessCallback callback) {
return base::WrapUnique(new BlockUiController(
std::move(watcher), snapshot_dir, std::move(callback)));
}
bool BlockUiController::ShowScreen() {
if (shown_) {
LOG(INFO) << "UI screen is present.";
return true;
}
LOG(INFO) << "Showing UI Screen";
// Once the screen is shown, it stays so until the daemon is stopped.
shown_ = launch_process_callback_.Run(GetShowScreenCommandLine(),
GetShowScreenOptions(snapshot_dir_));
if (!shown_)
LOG(ERROR) << "Failed to launch update_arc_data_snapshot screen";
watcher_->Init();
return shown_;
}
bool BlockUiController::UpdateProgress(int percent) {
if (!ShowScreen()) {
LOG(ERROR) << "Failed to start update_arc_data_snapshot_screen.";
return false;
}
DCHECK(shown_);
if (!launch_process_callback_.Run(GetUpdateProgressCommandLine(percent),
GetUpdateProgressOptions())) {
LOG(ERROR) << "Failed to update update_arc_data_snapshot";
return false;
}
return true;
}
BlockUiController::BlockUiController(std::unique_ptr<EscKeyWatcher> watcher,
const base::FilePath& snapshot_dir,
LaunchProcessCallback callback)
: watcher_(std::move(watcher)),
snapshot_dir_(snapshot_dir),
launch_process_callback_(std::move(callback)) {
DCHECK(watcher_);
}
} // namespace data_snapshotd
} // namespace arc