blob: 2e9c3fd11461715be1a05ad3bc00c8bf368334d8 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.locksettings;
import android.hardware.weaver.IWeaver;
import android.hardware.weaver.WeaverConfig;
import android.hardware.weaver.WeaverReadResponse;
import android.hardware.weaver.WeaverReadStatus;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Slog;
import java.util.ArrayList;
/**
* Adapt the legacy HIDL interface to present the AIDL interface.
*/
class WeaverHidlAdapter implements IWeaver {
private static final String TAG = "WeaverHidlAdapter";
private final android.hardware.weaver.V1_0.IWeaver mImpl;
WeaverHidlAdapter(android.hardware.weaver.V1_0.IWeaver impl) {
mImpl = impl;
}
@Override
public WeaverConfig getConfig() throws RemoteException {
final WeaverConfig[] res = new WeaverConfig[1];
mImpl.getConfig((int status, android.hardware.weaver.V1_0.WeaverConfig config) -> {
if (status == android.hardware.weaver.V1_0.WeaverStatus.OK) {
WeaverConfig aidlRes = new WeaverConfig();
aidlRes.slots = config.slots;
aidlRes.keySize = config.keySize;
aidlRes.valueSize = config.valueSize;
res[0] = aidlRes;
} else {
Slog.e(TAG,
"Failed to get HIDL weaver config. status: " + status
+ ", slots: " + config.slots);
}
});
return res[0];
}
@Override
public WeaverReadResponse read(int slotId, byte[] key)
throws RemoteException {
final WeaverReadResponse[] res = new WeaverReadResponse[1];
mImpl.read(
slotId, toByteArrayList(key),
(int inStatus, android.hardware.weaver.V1_0.WeaverReadResponse readResponse) -> {
WeaverReadResponse aidlRes =
new WeaverReadResponse();
switch (inStatus) {
case android.hardware.weaver.V1_0.WeaverReadStatus.OK:
aidlRes.status = WeaverReadStatus.OK;
break;
case android.hardware.weaver.V1_0.WeaverReadStatus.THROTTLE:
aidlRes.status = WeaverReadStatus.THROTTLE;
break;
case android.hardware.weaver.V1_0.WeaverReadStatus.INCORRECT_KEY:
aidlRes.status = WeaverReadStatus.INCORRECT_KEY;
break;
case android.hardware.weaver.V1_0.WeaverReadStatus.FAILED:
aidlRes.status = WeaverReadStatus.FAILED;
break;
default:
Slog.e(TAG, "Unexpected status in read: " + inStatus);
aidlRes.status = WeaverReadStatus.FAILED;
break;
}
aidlRes.timeout = readResponse.timeout;
aidlRes.value = fromByteArrayList(readResponse.value);
res[0] = aidlRes;
});
return res[0];
}
@Override
public void write(int slotId, byte[] key, byte[] value) throws RemoteException {
int writeStatus = mImpl.write(slotId, toByteArrayList(key), toByteArrayList(value));
if (writeStatus != android.hardware.weaver.V1_0.WeaverStatus.OK) {
throw new ServiceSpecificException(
IWeaver.STATUS_FAILED, "Failed IWeaver.write call, status: " + writeStatus);
}
}
@Override
public String getInterfaceHash() {
// We do not require the interface hash as the client.
throw new UnsupportedOperationException(
"WeaverHidlAdapter does not support getInterfaceHash");
}
@Override
public int getInterfaceVersion() {
// Supports only V2 which is at feature parity.
return 2;
}
@Override
public IBinder asBinder() {
// There is no IHwBinder to IBinder. Not required as the client.
throw new UnsupportedOperationException("WeaverHidlAdapter does not support asBinder");
}
private static ArrayList<Byte> toByteArrayList(byte[] data) {
ArrayList<Byte> result = new ArrayList<Byte>(data.length);
for (int i = 0; i < data.length; i++) {
result.add(data[i]);
}
return result;
}
private static byte[] fromByteArrayList(ArrayList<Byte> data) {
byte[] result = new byte[data.size()];
for (int i = 0; i < data.size(); i++) {
result[i] = data.get(i);
}
return result;
}
}