1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "BootControl.h"
18 #include <cstdint>
19
20 #include <android-base/logging.h>
21
22 using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus;
23 using ndk::ScopedAStatus;
24
25 namespace aidl::android::hardware::boot {
26
BootControl()27 BootControl::BootControl() {
28 CHECK(impl_.Init());
29 }
30
getActiveBootSlot(int32_t * _aidl_return)31 ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) {
32 *_aidl_return = impl_.GetActiveBootSlot();
33 return ScopedAStatus::ok();
34 }
35
getCurrentSlot(int32_t * _aidl_return)36 ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) {
37 *_aidl_return = impl_.GetCurrentSlot();
38 return ScopedAStatus::ok();
39 }
40
getNumberSlots(int32_t * _aidl_return)41 ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) {
42 *_aidl_return = impl_.GetNumberSlots();
43 return ScopedAStatus::ok();
44 }
45
46 namespace {
47
ToAIDLMergeStatus(HIDLMergeStatus status)48 static constexpr MergeStatus ToAIDLMergeStatus(HIDLMergeStatus status) {
49 switch (status) {
50 case HIDLMergeStatus::NONE:
51 return MergeStatus::NONE;
52 case HIDLMergeStatus::UNKNOWN:
53 return MergeStatus::UNKNOWN;
54 case HIDLMergeStatus::SNAPSHOTTED:
55 return MergeStatus::SNAPSHOTTED;
56 case HIDLMergeStatus::MERGING:
57 return MergeStatus::MERGING;
58 case HIDLMergeStatus::CANCELLED:
59 return MergeStatus::CANCELLED;
60 }
61 }
62
ToHIDLMergeStatus(MergeStatus status)63 static constexpr HIDLMergeStatus ToHIDLMergeStatus(MergeStatus status) {
64 switch (status) {
65 case MergeStatus::NONE:
66 return HIDLMergeStatus::NONE;
67 case MergeStatus::UNKNOWN:
68 return HIDLMergeStatus::UNKNOWN;
69 case MergeStatus::SNAPSHOTTED:
70 return HIDLMergeStatus::SNAPSHOTTED;
71 case MergeStatus::MERGING:
72 return HIDLMergeStatus::MERGING;
73 case MergeStatus::CANCELLED:
74 return HIDLMergeStatus::CANCELLED;
75 }
76 }
77
78 }
79
getSnapshotMergeStatus(MergeStatus * _aidl_return)80 ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) {
81 *_aidl_return = ToAIDLMergeStatus(impl_.GetSnapshotMergeStatus());
82 return ScopedAStatus::ok();
83 }
84
getSuffix(int32_t in_slot,std::string * _aidl_return)85 ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) {
86 if (!impl_.IsValidSlot(in_slot)) {
87 // Old HIDL hal returns empty string for invalid slots. We should maintain this behavior in
88 // AIDL for compatibility.
89 _aidl_return->clear();
90 } else {
91 *_aidl_return = impl_.GetSuffix(in_slot);
92 }
93 return ScopedAStatus::ok();
94 }
95
isSlotBootable(int32_t in_slot,bool * _aidl_return)96 ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) {
97 if (!impl_.IsValidSlot(in_slot)) {
98 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
99 INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
100 }
101 *_aidl_return = impl_.IsSlotBootable(in_slot);
102 return ScopedAStatus::ok();
103 }
104
isSlotMarkedSuccessful(int32_t in_slot,bool * _aidl_return)105 ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) {
106 if (!impl_.IsValidSlot(in_slot)) {
107 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
108 INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
109 }
110 *_aidl_return = impl_.IsSlotMarkedSuccessful(in_slot);
111 return ScopedAStatus::ok();
112 }
113
markBootSuccessful()114 ScopedAStatus BootControl::markBootSuccessful() {
115 if (!impl_.MarkBootSuccessful()) {
116 return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
117 "Operation failed");
118 }
119 return ScopedAStatus::ok();
120 }
121
setActiveBootSlot(int32_t in_slot)122 ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) {
123 if (!impl_.IsValidSlot(in_slot)) {
124 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
125 INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
126 }
127 if (!impl_.SetActiveBootSlot(in_slot)) {
128 return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
129 "Operation failed");
130 }
131 return ScopedAStatus::ok();
132 }
133
setSlotAsUnbootable(int32_t in_slot)134 ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) {
135 if (!impl_.IsValidSlot(in_slot)) {
136 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
137 INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
138 }
139 if (!impl_.SetSlotAsUnbootable(in_slot)) {
140 return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
141 "Operation failed");
142 }
143 return ScopedAStatus::ok();
144 }
145
setSnapshotMergeStatus(MergeStatus in_status)146 ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) {
147 if (!impl_.SetSnapshotMergeStatus(ToHIDLMergeStatus(in_status))) {
148 return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
149 "Operation failed");
150 }
151 return ScopedAStatus::ok();
152 }
153
154 } // namespace aidl::android::hardware::boot
155