blob: 8289b69230d001d6c28afbde269fb683931454d7 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/startup/browser_postlogin_params.h"
#include <optional>
#include <string>
#include "base/check_is_test.h"
#include "base/files/file_util.h"
#include "base/process/process.h"
#include "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/startup/startup.h"
namespace chromeos {
namespace {
// Reads and parses the post-login data to BrowserPostLoginParams.
// If the data is missing or empty, we didn't receive it from Ash, likely
// because Ash is shutting down and closing its end of the pipe. In that case,
// we terminate Lacros gracefully.
// If the data failed to parse because of a deserialization error, returns a
// null StructPtr.
crosapi::mojom::BrowserPostLoginParamsPtr ReadStartupBrowserPostLoginParams() {
std::optional<std::string> content = ReadPostLoginData();
if (!content.has_value() || content->empty()) {
// Ash shut down or crashed, so the pipe is broken or empty.
// Lacros should shut down gracefully instead of crashing.
// See crbug.com/1491478 for additional context.
base::Process::TerminateCurrentProcessImmediately(
RESULT_CODE_INVALID_POST_LOGIN_PARAMS);
}
crosapi::mojom::BrowserPostLoginParamsPtr result;
if (!crosapi::mojom::BrowserPostLoginParams::Deserialize(
content->data(), content->size(), &result)) {
LOG(ERROR) << "Failed to parse post-login data";
return {};
}
return result;
}
} // namespace
// static
void BrowserPostLoginParams::WaitForLogin() {
// TODO(crbug.com/1475643): added to investigate the cause of this crash.
// Please remove once the cause is identified.
LOG(WARNING) << "Waiting for login.";
auto* instance = GetInstanceInternal();
if (!instance->postlogin_params_) {
// Fetch the postlogin parameters, or wait for them to be available.
instance->postlogin_params_ = ReadStartupBrowserPostLoginParams();
CHECK(instance->postlogin_params_);
} else {
// This code path should only be reached in tests after calling
// SetPostLoginParamsForTests.
CHECK_IS_TEST();
}
// Signal that the user has logged in.
instance->logged_in_ = true;
}
// static
bool BrowserPostLoginParams::IsLoggedIn() {
return GetInstanceInternal()->logged_in_;
}
// static
void BrowserPostLoginParams::SetPostLoginParamsForTests(
crosapi::mojom::BrowserPostLoginParamsPtr postlogin_params) {
GetInstanceInternal()->postlogin_params_ = std::move(postlogin_params);
}
// static
base::ScopedFD BrowserPostLoginParams::CreatePostLoginData() {
CHECK(GetInstanceInternal()->postlogin_params_);
return chromeos::CreateMemFDFromBrowserPostLoginParams(
GetInstanceInternal()->postlogin_params_);
}
// static
const crosapi::mojom::BrowserPostLoginParams* BrowserPostLoginParams::Get() {
CHECK(GetInstanceInternal()->postlogin_params_);
return GetInstanceInternal()->postlogin_params_.get();
}
// static
BrowserPostLoginParams* BrowserPostLoginParams::GetInstanceInternal() {
static base::NoDestructor<BrowserPostLoginParams> browser_postlogin_params;
return browser_postlogin_params.get();
}
BrowserPostLoginParams::BrowserPostLoginParams() = default;
} // namespace chromeos