blob: 37540d039b9e70ba47eba82c8866e60b8f7373c4 [file] [log] [blame]
Andrew Scull5d7027d2017-04-12 11:46:27 +01001/*
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
17package com.android.server.oemlock;
18
19import android.annotation.Nullable;
20import android.content.Context;
21import android.hardware.oemlock.V1_0.IOemLock;
22import android.hardware.oemlock.V1_0.OemLockSecureStatus;
23import android.hardware.oemlock.V1_0.OemLockStatus;
24import android.os.RemoteException;
Andrew Scull5d7027d2017-04-12 11:46:27 +010025import android.util.Slog;
26
27import java.util.ArrayList;
28import java.util.NoSuchElementException;
29
30/**
31 * Uses the OEM lock HAL.
32 */
33class VendorLock extends OemLock {
34 private static final String TAG = "OemLock";
35
36 private Context mContext;
37 private IOemLock mOemLock;
38
39 static IOemLock getOemLockHalService() {
40 try {
41 return IOemLock.getService();
42 } catch (NoSuchElementException e) {
43 Slog.i(TAG, "OemLock HAL not present on device");
44 return null;
45 } catch (RemoteException e) {
46 throw e.rethrowFromSystemServer();
47 }
48 }
49
50 VendorLock(Context context, IOemLock oemLock) {
51 mContext = context;
52 mOemLock = oemLock;
53 }
54
55 @Override
Andrew Scull23a1a5f2018-11-27 16:45:58 +000056 @Nullable
57 String getLockName() {
58 final Integer[] requestStatus = new Integer[1];
59 final String[] lockName = new String[1];
60
61 try {
62 mOemLock.getName((status, name) -> {
63 requestStatus[0] = status;
64 lockName[0] = name;
65 });
66 } catch (RemoteException e) {
67 Slog.e(TAG, "Failed to get name from HAL", e);
68 throw e.rethrowFromSystemServer();
69 }
70
71 switch (requestStatus[0]) {
72 case OemLockStatus.OK:
73 // Success
74 return lockName[0];
75
76 case OemLockStatus.FAILED:
77 Slog.e(TAG, "Failed to get OEM lock name.");
78 return null;
79
80 default:
81 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
82 return null;
83 }
84 }
85
86 @Override
Andrew Scull5d7027d2017-04-12 11:46:27 +010087 void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
88 try {
Andrew Scull23a1a5f2018-11-27 16:45:58 +000089 ArrayList<Byte> signatureBytes = toByteArrayList(signature);
90 switch (mOemLock.setOemUnlockAllowedByCarrier(allowed, signatureBytes)) {
Andrew Scull5d7027d2017-04-12 11:46:27 +010091 case OemLockSecureStatus.OK:
92 Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed);
93 return;
94
95 case OemLockSecureStatus.INVALID_SIGNATURE:
Andrew Scull23a1a5f2018-11-27 16:45:58 +000096 if (signatureBytes.isEmpty()) {
97 throw new IllegalArgumentException("Signature required for carrier unlock");
98 }
Andrew Scull5d7027d2017-04-12 11:46:27 +010099 throw new SecurityException(
100 "Invalid signature used in attempt to carrier unlock");
101
102 default:
103 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
104 // Fallthrough
105 case OemLockSecureStatus.FAILED:
106 throw new RuntimeException("Failed to set carrier OEM unlock state");
107 }
108 } catch (RemoteException e) {
109 Slog.e(TAG, "Failed to set carrier state with HAL", e);
110 throw e.rethrowFromSystemServer();
111 }
112 }
113
114 @Override
115 boolean isOemUnlockAllowedByCarrier() {
116 final Integer[] requestStatus = new Integer[1];
117 final Boolean[] allowedByCarrier = new Boolean[1];
118
119 try {
120 mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> {
121 requestStatus[0] = status;
122 allowedByCarrier[0] = allowed;
123 });
124 } catch (RemoteException e) {
125 Slog.e(TAG, "Failed to get carrier state from HAL");
126 throw e.rethrowFromSystemServer();
127 }
128
129 switch (requestStatus[0]) {
130 case OemLockStatus.OK:
131 // Success
132 return allowedByCarrier[0];
133
134 default:
135 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
136 // Fallthrough
137 case OemLockStatus.FAILED:
138 throw new RuntimeException("Failed to get carrier OEM unlock state");
139 }
140 }
141
142 @Override
143 void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
144 try {
145 switch (mOemLock.setOemUnlockAllowedByDevice(allowedByDevice)) {
146 case OemLockSecureStatus.OK:
147 Slog.i(TAG, "Updated device allows OEM lock state to: " + allowedByDevice);
148 return;
149
150 default:
151 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
152 // Fallthrough
153 case OemLockSecureStatus.FAILED:
154 throw new RuntimeException("Failed to set device OEM unlock state");
155 }
156 } catch (RemoteException e) {
157 Slog.e(TAG, "Failed to set device state with HAL", e);
158 throw e.rethrowFromSystemServer();
159 }
160 }
161
162 @Override
163 boolean isOemUnlockAllowedByDevice() {
164 final Integer[] requestStatus = new Integer[1];
165 final Boolean[] allowedByDevice = new Boolean[1];
166
167 try {
168 mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> {
169 requestStatus[0] = status;
170 allowedByDevice[0] = allowed;
171 });
172 } catch (RemoteException e) {
173 Slog.e(TAG, "Failed to get devie state from HAL");
174 throw e.rethrowFromSystemServer();
175 }
176
177 switch (requestStatus[0]) {
178 case OemLockStatus.OK:
179 // Success
180 return allowedByDevice[0];
181
182 default:
183 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
184 // Fallthrough
185 case OemLockStatus.FAILED:
186 throw new RuntimeException("Failed to get device OEM unlock state");
187 }
188 }
189
Andrew Scull23a1a5f2018-11-27 16:45:58 +0000190 private ArrayList<Byte> toByteArrayList(byte[] data) {
Andrew Scull5d7027d2017-04-12 11:46:27 +0100191 if (data == null) {
Andrew Scull23a1a5f2018-11-27 16:45:58 +0000192 return new ArrayList<Byte>();
Andrew Scull5d7027d2017-04-12 11:46:27 +0100193 }
194 ArrayList<Byte> result = new ArrayList<Byte>(data.length);
195 for (final byte b : data) {
196 result.add(b);
197 }
198 return result;
199 }
200}