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 <android-base/logging.h>
18
19 #include <cutils/properties.h>
20
21 #include <aidl/android/hardware/boot/IBootControl.h>
22
23 #include <aidl/Vintf.h>
24 #include <android/binder_manager.h>
25 #include <gtest/gtest.h>
26 #include <hidl/GtestPrinter.h>
27 #include <hidl/ServiceManagement.h>
28
29 #include <unordered_set>
30
31 using aidl::android::hardware::boot::IBootControl;
32 using std::string;
33 using std::unordered_set;
34
35 // The main test class for the Boot HIDL HAL.
36 class BootAidlTest : public ::testing::TestWithParam<std::string> {
37 public:
SetUp()38 virtual void SetUp() override {
39 const auto instance_name = GetParam();
40 ASSERT_TRUE(AServiceManager_isDeclared(instance_name.c_str()))
41 << " instance " << instance_name << " not declared.";
42 boot = ::aidl::android::hardware::boot::IBootControl::fromBinder(
43 ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
44 ASSERT_NE(boot, nullptr);
45 }
46
47 std::shared_ptr<IBootControl> boot;
48 };
49
50 // validity check Boot::getNumberSlots().
TEST_P(BootAidlTest,GetNumberSlots)51 TEST_P(BootAidlTest, GetNumberSlots) {
52 int32_t slots{};
53 boot->getNumberSlots(&slots);
54 ASSERT_LE(2, slots);
55 }
56
57 // validity check Boot::getCurrentSlot().
TEST_P(BootAidlTest,GetCurrentSlot)58 TEST_P(BootAidlTest, GetCurrentSlot) {
59 int curSlot = -1;
60 boot->getCurrentSlot(&curSlot);
61 int slots = 0;
62 boot->getNumberSlots(&slots);
63 ASSERT_LT(curSlot, slots);
64 }
65
66 // validity check Boot::markBootSuccessful().
TEST_P(BootAidlTest,MarkBootSuccessful)67 TEST_P(BootAidlTest, MarkBootSuccessful) {
68 const auto result = boot->markBootSuccessful();
69 ASSERT_TRUE(result.isOk());
70 int curSlot = 0;
71 boot->getCurrentSlot(&curSlot);
72 bool ret = false;
73 boot->isSlotMarkedSuccessful(curSlot, &ret);
74 ASSERT_TRUE(ret);
75 }
76
TEST_P(BootAidlTest,SetActiveBootSlot)77 TEST_P(BootAidlTest, SetActiveBootSlot) {
78 int curSlot = -1;
79 boot->getCurrentSlot(&curSlot);
80 ASSERT_GE(curSlot, 0);
81 int otherSlot = curSlot ? 0 : 1;
82 bool otherBootable = true;
83 boot->isSlotBootable(otherSlot, &otherBootable);
84
85 for (int s = 0; s < 2; s++) {
86 const auto result = boot->setActiveBootSlot(s);
87 ASSERT_TRUE(result.isOk());
88 }
89 {
90 // Restore original flags to avoid problems on reboot
91 auto result = boot->setActiveBootSlot(curSlot);
92 ASSERT_TRUE(result.isOk());
93
94 if (!otherBootable) {
95 const auto result = boot->setSlotAsUnbootable(otherSlot);
96 ASSERT_TRUE(result.isOk());
97 }
98
99 result = boot->markBootSuccessful();
100 ASSERT_TRUE(result.isOk());
101 }
102 {
103 int slots = 0;
104 boot->getNumberSlots(&slots);
105 const auto result = boot->setActiveBootSlot(slots);
106 ASSERT_FALSE(result.isOk()) << "setActiveBootSlot on invalid slot should fail";
107 }
108 }
109
TEST_P(BootAidlTest,SetSlotAsUnbootable)110 TEST_P(BootAidlTest, SetSlotAsUnbootable) {
111 int curSlot = -1;
112 boot->getCurrentSlot(&curSlot);
113 ASSERT_GE(curSlot, 0);
114 int otherSlot = curSlot ? 0 : 1;
115 bool otherBootable = false;
116 boot->isSlotBootable(otherSlot, &otherBootable);
117 {
118 auto result = boot->setSlotAsUnbootable(otherSlot);
119 ASSERT_TRUE(result.isOk());
120 boot->isSlotBootable(otherSlot, &otherBootable);
121 ASSERT_FALSE(otherBootable);
122
123 // Restore original flags to avoid problems on reboot
124 if (otherBootable) {
125 result = boot->setActiveBootSlot(otherSlot);
126 ASSERT_TRUE(result.isOk());
127 }
128 result = boot->setActiveBootSlot(curSlot);
129 ASSERT_TRUE(result.isOk());
130 result = boot->markBootSuccessful();
131 ASSERT_TRUE(result.isOk());
132 }
133 {
134 int32_t slots = 0;
135 boot->getNumberSlots(&slots);
136 const auto result = boot->setSlotAsUnbootable(slots);
137 ASSERT_FALSE(result.isOk());
138 }
139 }
140
141 // validity check Boot::isSlotBootable() on good and bad inputs.
TEST_P(BootAidlTest,IsSlotBootable)142 TEST_P(BootAidlTest, IsSlotBootable) {
143 for (int s = 0; s < 2; s++) {
144 bool bootable = false;
145 const auto res = boot->isSlotBootable(s, &bootable);
146 ASSERT_TRUE(res.isOk()) << res.getMessage();
147 }
148 int32_t slots = 0;
149 boot->getNumberSlots(&slots);
150 bool bootable = false;
151 const auto res = boot->isSlotBootable(slots, &bootable);
152 ASSERT_FALSE(res.isOk());
153 }
154
155 // validity check Boot::isSlotMarkedSuccessful() on good and bad inputs.
TEST_P(BootAidlTest,IsSlotMarkedSuccessful)156 TEST_P(BootAidlTest, IsSlotMarkedSuccessful) {
157 for (int32_t s = 0; s < 2; s++) {
158 bool isSuccess = false;
159 const auto res = boot->isSlotMarkedSuccessful(s, &isSuccess);
160 }
161 int32_t slots = 0;
162 boot->getNumberSlots(&slots);
163 bool isSuccess = false;
164 const auto res = boot->isSlotMarkedSuccessful(slots, &isSuccess);
165 ASSERT_FALSE(res.isOk());
166 }
167
168 // validity check Boot::getSuffix() on good and bad inputs.
TEST_P(BootAidlTest,GetSuffix)169 TEST_P(BootAidlTest, GetSuffix) {
170 string suffixStr;
171 unordered_set<string> suffixes;
172 int numSlots = 0;
173 boot->getNumberSlots(&numSlots);
174 for (int32_t i = 0; i < numSlots; i++) {
175 std::string suffix;
176 const auto result = boot->getSuffix(i, &suffixStr);
177 ASSERT_TRUE(result.isOk());
178 ASSERT_EQ('_', suffixStr[0]);
179 ASSERT_LE((unsigned)2, suffixStr.size());
180 suffixes.insert(suffixStr);
181 }
182 // All suffixes should be unique
183 ASSERT_EQ(numSlots, suffixes.size());
184 {
185 const string emptySuffix = "";
186 const auto result = boot->getSuffix(numSlots, &suffixStr);
187 ASSERT_TRUE(result.isOk());
188 ASSERT_EQ(suffixStr, emptySuffix);
189 }
190 }
191
192 INSTANTIATE_TEST_SUITE_P(
193 PerInstance, BootAidlTest,
194 testing::ValuesIn(android::getAidlHalInstanceNames(IBootControl::descriptor)));
195 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BootAidlTest);
196