blob: a8b6d67b0b717f8eb4d6d2a49b4175b7769cd4cd [file] [log] [blame]
// Copyright 2020 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 "hermes/manager.h"
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/callback.h>
#include <chromeos/dbus/service_constants.h>
#include <google-lpa/lpa/core/lpa.h>
#include "hermes/lpa_util.h"
using lpa::proto::ProfileInfo;
namespace hermes {
namespace {
const char kHermesErrorDomain[] = "Hermes";
} // namespace
Manager::Manager(const scoped_refptr<dbus::Bus>& bus, LpaContext* context)
: org::chromium::Hermes::ManagerAdaptor(this),
bus_(bus),
dbus_object_(nullptr,
bus_,
org::chromium::Hermes::ManagerAdaptor::GetObjectPath()),
context_(context) {
RegisterWithDBusObject(&dbus_object_);
dbus_object_.RegisterAndBlock();
RetrieveInstalledProfiles();
}
void Manager::InstallProfileFromActivationCode(
std::unique_ptr<DBusResponse<dbus::ObjectPath>> response,
const std::string& in_activation_code) {
auto profile_cb = [response{std::shared_ptr<DBusResponse<dbus::ObjectPath>>(
std::move(response))},
this](lpa::proto::ProfileInfo& profile, int error) {
auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
if (decoded_error) {
response->ReplyWithError(decoded_error.get());
return;
}
profiles_.push_back(std::make_unique<Profile>(bus_, context_, profile));
UpdateProfilesProperty();
response->Return(profiles_.back()->object_path());
};
if (in_activation_code.empty()) {
context_->lpa->GetDefaultProfileFromSmdp("", context_->executor,
std::move(profile_cb));
return;
}
lpa::core::Lpa::DownloadOptions options;
options.enable_profile = false;
options.allow_policy_rules = false;
context_->lpa->DownloadProfile(in_activation_code, std::move(options),
context_->executor, std::move(profile_cb));
}
void Manager::InstallProfileFromEvent(
std::unique_ptr<DBusResponse<dbus::ObjectPath>> response,
const std::string& /*in_smdp_address*/,
const std::string& /*in_event_id*/) {
response->ReplyWithError(
FROM_HERE, kHermesErrorDomain, "UnsupportedMethod",
"This method is not supported until crbug.com/1071470 is implemented");
}
void Manager::UninstallProfile(std::unique_ptr<DBusResponse<>> response,
const dbus::ObjectPath& in_profile) {
const Profile* matching_profile = nullptr;
for (auto& profile : profiles_) {
if (profile->object_path() == in_profile) {
matching_profile = profile.get();
break;
}
}
if (!matching_profile) {
response->ReplyWithError(FROM_HERE, kHermesErrorDomain, "InvalidParameter",
"Could not find Profile " + in_profile.value());
return;
}
// Wait for lpa call to complete successfully before removing element from
// |profiles_|.
auto profile_cb =
[response{std::shared_ptr<DBusResponse<>>(std::move(response))},
in_profile, this](int error) {
auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
if (decoded_error) {
response->ReplyWithError(decoded_error.get());
return;
}
auto iter = std::find_if(profiles_.begin(), profiles_.end(),
[in_profile](const auto& profile) {
return profile->object_path() == in_profile;
});
CHECK(iter != profiles_.end());
profiles_.erase(iter);
UpdateProfilesProperty();
response->Return();
};
context_->lpa->DeleteProfile(matching_profile->GetIccid(), context_->executor,
std::move(profile_cb));
}
void Manager::RequestPendingEvents(
std::unique_ptr<DBusResponse<std::vector<Event>>> response) {
// TODO(crbug.com/1071470) This is stubbed until google-lpa supports SM-DS.
response->Return({});
}
void Manager::UpdateProfilesProperty() {
std::vector<dbus::ObjectPath> profile_paths;
for (auto& profile : profiles_) {
profile_paths.push_back(profile->object_path());
}
SetProfiles(profile_paths);
}
void Manager::RetrieveInstalledProfiles() {
auto cb = [this](std::vector<lpa::proto::ProfileInfo>& profiles, int error) {
auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
if (decoded_error) {
LOG(ERROR) << "Failed to retrieve installed profiles";
return;
}
for (auto& profile : profiles) {
profiles_.push_back(std::make_unique<Profile>(bus_, context_, profile));
}
UpdateProfilesProperty();
};
context_->lpa->GetInstalledProfiles(context_->executor, std::move(cb));
}
void Manager::SetTestMode(bool /*in_is_test_mode*/) {
// TODO(akhouderchah) This is a no-op until the Lpa interface allows for
// switching certificate directory without recreating the Lpa object.
NOTIMPLEMENTED();
}
} // namespace hermes