• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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