1/*
2 * Copyright (C) 2017 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/hardware/oemlock/1.0/IOemLock.h>
18
19#include <VtsHalHidlTargetTestBase.h>
20
21using ::android::hardware::oemlock::V1_0::IOemLock;
22using ::android::hardware::oemlock::V1_0::OemLockStatus;
23using ::android::hardware::oemlock::V1_0::OemLockSecureStatus;
24using ::android::hardware::hidl_string;
25using ::android::hardware::hidl_vec;
26using ::android::sp;
27
28struct OemLockHidlTest : public ::testing::VtsHalHidlTargetTestBase {
29    virtual void SetUp() override {
30        oemlock = ::testing::VtsHalHidlTargetTestBase::getService<IOemLock>();
31        ASSERT_NE(oemlock, nullptr);
32    }
33
34    virtual void TearDown() override {}
35
36    sp<IOemLock> oemlock;
37};
38
39/*
40 * Check the name can be retrieved
41 */
42TEST_F(OemLockHidlTest, GetName) {
43    std::string name;
44    OemLockStatus status;
45
46    bool callbackCalled = false;
47    const auto ret = oemlock->getName([&](OemLockStatus s, hidl_string n) {
48        callbackCalled = true;
49        status = s;
50        name = n.c_str();
51    });
52
53    ASSERT_TRUE(ret.isOk());
54    ASSERT_TRUE(callbackCalled);
55    EXPECT_EQ(status, OemLockStatus::OK);
56    // Any value acceptable
57};
58
59/*
60 * Check the unlock allowed by device state can be queried
61 */
62TEST_F(OemLockHidlTest, QueryUnlockAllowedByDevice) {
63    bool allowed;
64    OemLockStatus status;
65
66    bool callbackCalled = false;
67    const auto ret = oemlock->isOemUnlockAllowedByDevice([&](OemLockStatus s, bool a) {
68        callbackCalled = true;
69        status = s;
70        allowed = a;
71    });
72
73    ASSERT_TRUE(ret.isOk());
74    ASSERT_TRUE(callbackCalled);
75    EXPECT_EQ(status, OemLockStatus::OK);
76    // Any value acceptable
77}
78
79/*
80 * Check unlock allowed by device state can be toggled
81 */
82TEST_F(OemLockHidlTest, AllowedByDeviceCanBeToggled) {
83    bool allowed;
84    OemLockStatus status;
85
86    auto getAllowedCallback = [&](OemLockStatus s, bool a) {
87        status = s;
88        allowed = a;
89    };
90
91    // Get the original state so it can be restored
92    const auto get_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
93    ASSERT_TRUE(get_ret.isOk());
94    ASSERT_EQ(status, OemLockStatus::OK);
95    const bool originallyAllowed = allowed;
96
97    // Toggle the state
98    const auto set_ret = oemlock->setOemUnlockAllowedByDevice(!originallyAllowed);
99    ASSERT_TRUE(set_ret.isOk());
100    ASSERT_EQ(set_ret, OemLockStatus::OK);
101    const auto check_set_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
102    ASSERT_TRUE(check_set_ret.isOk());
103    ASSERT_EQ(status, OemLockStatus::OK);
104    ASSERT_EQ(allowed, !originallyAllowed);
105
106    // Restore the state
107    const auto restore_ret = oemlock->setOemUnlockAllowedByDevice(originallyAllowed);
108    ASSERT_TRUE(restore_ret.isOk());
109    ASSERT_EQ(restore_ret, OemLockStatus::OK);
110    const auto check_restore_ret = oemlock->isOemUnlockAllowedByDevice(getAllowedCallback);
111    ASSERT_TRUE(check_restore_ret.isOk());
112    ASSERT_EQ(status, OemLockStatus::OK);
113    ASSERT_EQ(allowed, originallyAllowed);
114};
115
116/*
117 * Check the unlock allowed by device state can be queried
118 */
119TEST_F(OemLockHidlTest, QueryUnlockAllowedByCarrier) {
120    bool allowed;
121    OemLockStatus status;
122
123    bool callbackCalled = false;
124    const auto ret = oemlock->isOemUnlockAllowedByCarrier([&](OemLockStatus s, bool a) {
125        callbackCalled = true;
126        status = s;
127        allowed = a;
128    });
129
130    ASSERT_TRUE(ret.isOk());
131    ASSERT_TRUE(callbackCalled);
132    EXPECT_EQ(status, OemLockStatus::OK);
133    // Any value acceptable
134}
135
136/*
137 * Attempt to check unlock allowed by carrier can be toggled
138 *
139 * The implementation may involve a signature which cannot be tested here. That
140 * is a valid implementation so the test will pass. If there is no signature
141 * required, the test will toggle the value.
142 */
143TEST_F(OemLockHidlTest, CarrierUnlock) {
144    const hidl_vec<uint8_t> noSignature = {};
145    bool allowed;
146    OemLockStatus status;
147
148    auto getAllowedCallback = [&](OemLockStatus s, bool a) {
149        status = s;
150        allowed = a;
151    };
152
153    // Get the original state so it can be restored
154    const auto get_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
155    ASSERT_TRUE(get_ret.isOk());
156    ASSERT_EQ(status, OemLockStatus::OK);
157    const bool originallyAllowed = allowed;
158
159    if (originallyAllowed) {
160        // Only applied to locked devices
161        return;
162    }
163
164    // Toggle the state
165    const auto set_ret = oemlock->setOemUnlockAllowedByCarrier(!originallyAllowed, noSignature);
166    ASSERT_TRUE(set_ret.isOk());
167    ASSERT_NE(set_ret, OemLockSecureStatus::FAILED);
168    const auto check_set_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
169    ASSERT_TRUE(check_set_ret.isOk());
170    ASSERT_EQ(status, OemLockStatus::OK);
171
172    if (set_ret == OemLockSecureStatus::INVALID_SIGNATURE) {
173        // Signature is required so we cannot toggle the value in the test, but this is allowed
174        ASSERT_EQ(allowed, originallyAllowed);
175        return;
176    }
177
178    ASSERT_EQ(set_ret, OemLockSecureStatus::OK);
179    ASSERT_EQ(allowed, !originallyAllowed);
180
181    // Restore the state
182    const auto restore_ret = oemlock->setOemUnlockAllowedByCarrier(originallyAllowed, noSignature);
183    ASSERT_TRUE(restore_ret.isOk());
184    ASSERT_EQ(restore_ret, OemLockSecureStatus::OK);
185    const auto check_restore_ret = oemlock->isOemUnlockAllowedByCarrier(getAllowedCallback);
186    ASSERT_TRUE(check_restore_ret.isOk());
187    ASSERT_EQ(status, OemLockStatus::OK);
188    ASSERT_EQ(allowed, originallyAllowed);
189};
190