Home | History | Annotate | Download | only in oemlock
      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 package com.android.server.oemlock;
     18 
     19 import android.annotation.Nullable;
     20 import android.content.Context;
     21 import android.hardware.oemlock.V1_0.IOemLock;
     22 import android.hardware.oemlock.V1_0.OemLockSecureStatus;
     23 import android.hardware.oemlock.V1_0.OemLockStatus;
     24 import android.os.RemoteException;
     25 import android.os.UserHandle;
     26 import android.os.UserManager;
     27 import android.util.Slog;
     28 
     29 import java.util.ArrayList;
     30 import java.util.NoSuchElementException;
     31 
     32 /**
     33  * Uses the OEM lock HAL.
     34  */
     35 class 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 }
    168