1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/borealis/borealis_launch_options.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/ash/borealis/borealis_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "components/prefs/pref_service.h"
#include "third_party/re2/src/re2/re2.h"
namespace borealis {
namespace {
const char kExtraDiskSwitch[] = "extra-disk";
const char kAutoShutdownSwitch[] = "auto-shutdown";
bool IsDeveloperMode() {
std::string output;
if (!base::GetAppOutput({"/usr/bin/crossystem", "cros_debug"}, &output)) {
return false;
}
return output == "1";
}
// Parses the borealis options string into a struct as per the comma-separated
// "key=value" list described in the borealis_launch_options.h file.
//
// For historic reasons: "--foo=bar" is treated as "foo=bar" and ";" (semicolon)
// is treated as an additional separator to ",".
BorealisLaunchOptions::Options ParseOptions(const std::string& options_string) {
// Only devs/tests are allowed to modify these.
if (!IsDeveloperMode()) {
return {};
}
LOG(WARNING) << "Overriding borealis options with: " << options_string;
BorealisLaunchOptions::Options opts;
// We parse key=value pairs using regex:
// - "-*" consumes leading "-"s, for compatibility with the old format
// - "([^-][^=]*)" matches the key
// - "(.*)" matches the value
RE2 pattern("-*([^-][^=]*)=(.*)");
for (std::string option :
base::SplitString(options_string, ";,", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY)) {
std::string key, val;
if (!RE2::FullMatch(option, pattern, &key, &val))
continue;
if (key == kExtraDiskSwitch) {
opts.extra_disk = base::FilePath(val);
} else if (key == kAutoShutdownSwitch) {
opts.auto_shutdown = base::ToLowerASCII(val[0]) == 't';
}
}
return opts;
}
} // namespace
BorealisLaunchOptions::Options::Options() = default;
BorealisLaunchOptions::Options::Options(const Options&) = default;
BorealisLaunchOptions::Options::~Options() = default;
BorealisLaunchOptions::BorealisLaunchOptions(Profile* profile)
: options_(profile->GetPrefs()->GetString(prefs::kExtraLaunchOptions)) {}
void BorealisLaunchOptions::Build(
base::OnceCallback<void(BorealisLaunchOptions::Options)> callback) const {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, base::MayBlock(), base::BindOnce(&ParseOptions, options_),
std::move(callback));
}
void BorealisLaunchOptions::ForceOptions(std::string options) {
options_ = options;
}
} // namespace borealis
|