blob: 1b9de36123671fdcbcb11a190027c16ed6612771 [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;
25import android.os.UserHandle;
26import android.os.UserManager;
27import android.util.Slog;
28
29import java.util.ArrayList;
30import java.util.NoSuchElementException;
31
32/**
33 * Uses the OEM lock HAL.
34 */
35class VendorLock extends OemLock {
36 private static final String TAG = "OemLock";
37
38 private Context mContext;
39 private IOemLock mOemLock;
40
41 static IOemLock getOemLockHalService() {
42 try {
43 return IOemLock.getService();
44 } catch (NoSuchElementException e) {
45 Slog.i(TAG, "OemLock HAL not present on device");
46 return null;
47 } catch (RemoteException e) {
48 throw e.rethrowFromSystemServer();
49 }
50 }
51
52 VendorLock(Context context, IOemLock oemLock) {
53 mContext = context;
54 mOemLock = oemLock;
55 }
56
57 @Override
58 void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
59 try {
60 switch (mOemLock.setOemUnlockAllowedByCarrier(allowed, toByteArrayList(signature))) {
61 case OemLockSecureStatus.OK:
62 Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed);
63 return;
64
65 case OemLockSecureStatus.INVALID_SIGNATURE:
66 throw new SecurityException(
67 "Invalid signature used in attempt to carrier unlock");
68
69 default:
70 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
71 // Fallthrough
72 case OemLockSecureStatus.FAILED:
73 throw new RuntimeException("Failed to set carrier OEM unlock state");
74 }
75 } catch (RemoteException e) {
76 Slog.e(TAG, "Failed to set carrier state with HAL", e);
77 throw e.rethrowFromSystemServer();
78 }
79 }
80
81 @Override
82 boolean isOemUnlockAllowedByCarrier() {
83 final Integer[] requestStatus = new Integer[1];
84 final Boolean[] allowedByCarrier = new Boolean[1];
85
86 try {
87 mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> {
88 requestStatus[0] = status;
89 allowedByCarrier[0] = allowed;
90 });
91 } catch (RemoteException e) {
92 Slog.e(TAG, "Failed to get carrier state from HAL");
93 throw e.rethrowFromSystemServer();
94 }
95
96 switch (requestStatus[0]) {
97 case OemLockStatus.OK:
98 // Success
99 return allowedByCarrier[0];
100
101 default:
102 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
103 // Fallthrough
104 case OemLockStatus.FAILED:
105 throw new RuntimeException("Failed to get carrier OEM unlock state");
106 }
107 }
108
109 @Override
110 void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
111 try {
112 switch (mOemLock.setOemUnlockAllowedByDevice(allowedByDevice)) {
113 case OemLockSecureStatus.OK:
114 Slog.i(TAG, "Updated device allows OEM lock state to: " + allowedByDevice);
115 return;
116
117 default:
118 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
119 // Fallthrough
120 case OemLockSecureStatus.FAILED:
121 throw new RuntimeException("Failed to set device OEM unlock state");
122 }
123 } catch (RemoteException e) {
124 Slog.e(TAG, "Failed to set device state with HAL", e);
125 throw e.rethrowFromSystemServer();
126 }
127 }
128
129 @Override
130 boolean isOemUnlockAllowedByDevice() {
131 final Integer[] requestStatus = new Integer[1];
132 final Boolean[] allowedByDevice = new Boolean[1];
133
134 try {
135 mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> {
136 requestStatus[0] = status;
137 allowedByDevice[0] = allowed;
138 });
139 } catch (RemoteException e) {
140 Slog.e(TAG, "Failed to get devie state from HAL");
141 throw e.rethrowFromSystemServer();
142 }
143
144 switch (requestStatus[0]) {
145 case OemLockStatus.OK:
146 // Success
147 return allowedByDevice[0];
148
149 default:
150 Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
151 // Fallthrough
152 case OemLockStatus.FAILED:
153 throw new RuntimeException("Failed to get device OEM unlock state");
154 }
155 }
156
157 private ArrayList toByteArrayList(byte[] data) {
158 if (data == null) {
159 return null;
160 }
161 ArrayList<Byte> result = new ArrayList<Byte>(data.length);
162 for (final byte b : data) {
163 result.add(b);
164 }
165 return result;
166 }
167}