1/* 2 * Copyright (C) 2018 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 "VersionedIDevice.h" 18 19#include "Utils.h" 20 21#include <android-base/logging.h> 22 23namespace android { 24namespace nn { 25 26// HIDL guarantees all V1_1 interfaces inherit from their corresponding V1_0 interfaces. 27VersionedIDevice::VersionedIDevice(sp<V1_0::IDevice> device) : 28 mDeviceV1_0(device), 29 mDeviceV1_1(V1_1::IDevice::castFrom(mDeviceV1_0).withDefault(nullptr)) {} 30 31std::pair<ErrorStatus, Capabilities> VersionedIDevice::getCapabilities() { 32 std::pair<ErrorStatus, Capabilities> result; 33 34 if (mDeviceV1_1 != nullptr) { 35 Return<void> ret = mDeviceV1_1->getCapabilities_1_1( 36 [&result](ErrorStatus error, const Capabilities& capabilities) { 37 result = std::make_pair(error, capabilities); 38 }); 39 if (!ret.isOk()) { 40 LOG(ERROR) << "getCapabilities_1_1 failure: " << ret.description(); 41 return {ErrorStatus::GENERAL_FAILURE, {}}; 42 } 43 } else if (mDeviceV1_0 != nullptr) { 44 Return<void> ret = mDeviceV1_0->getCapabilities( 45 [&result](ErrorStatus error, const V1_0::Capabilities& capabilities) { 46 result = std::make_pair(error, convertToV1_1(capabilities)); 47 }); 48 if (!ret.isOk()) { 49 LOG(ERROR) << "getCapabilities failure: " << ret.description(); 50 return {ErrorStatus::GENERAL_FAILURE, {}}; 51 } 52 } else { 53 LOG(ERROR) << "Device not available!"; 54 return {ErrorStatus::DEVICE_UNAVAILABLE, {}}; 55 } 56 57 return result; 58} 59 60std::pair<ErrorStatus, hidl_vec<bool>> VersionedIDevice::getSupportedOperations( 61 const Model& model) { 62 std::pair<ErrorStatus, hidl_vec<bool>> result; 63 64 if (mDeviceV1_1 != nullptr) { 65 Return<void> ret = mDeviceV1_1->getSupportedOperations_1_1( 66 model, [&result](ErrorStatus error, const hidl_vec<bool>& supported) { 67 result = std::make_pair(error, supported); 68 }); 69 if (!ret.isOk()) { 70 LOG(ERROR) << "getSupportedOperations_1_1 failure: " << ret.description(); 71 return {ErrorStatus::GENERAL_FAILURE, {}}; 72 } 73 } else if (mDeviceV1_0 != nullptr && compliantWithV1_0(model)) { 74 Return<void> ret = mDeviceV1_0->getSupportedOperations( 75 convertToV1_0(model), [&result](ErrorStatus error, const hidl_vec<bool>& supported) { 76 result = std::make_pair(error, supported); 77 }); 78 if (!ret.isOk()) { 79 LOG(ERROR) << "getSupportedOperations failure: " << ret.description(); 80 return {ErrorStatus::GENERAL_FAILURE, {}}; 81 } 82 } else { 83 // TODO: partition the model such that v1.1 ops are not passed to v1.0 84 // device 85 LOG(ERROR) << "Could not handle getSupportedOperations!"; 86 return {ErrorStatus::GENERAL_FAILURE, {}}; 87 } 88 89 return result; 90} 91 92ErrorStatus VersionedIDevice::prepareModel(const Model& model, ExecutionPreference preference, 93 const sp<IPreparedModelCallback>& callback) { 94 if (mDeviceV1_1 != nullptr) { 95 Return<ErrorStatus> ret = mDeviceV1_1->prepareModel_1_1(model, preference, callback); 96 if (!ret.isOk()) { 97 LOG(ERROR) << "prepareModel_1_1 failure: " << ret.description(); 98 return ErrorStatus::GENERAL_FAILURE; 99 } 100 return static_cast<ErrorStatus>(ret); 101 } else if (mDeviceV1_0 != nullptr && compliantWithV1_0(model)) { 102 Return<ErrorStatus> ret = mDeviceV1_0->prepareModel(convertToV1_0(model), callback); 103 if (!ret.isOk()) { 104 LOG(ERROR) << "prepareModel failure: " << ret.description(); 105 return ErrorStatus::GENERAL_FAILURE; 106 } 107 return static_cast<ErrorStatus>(ret); 108 } else { 109 // TODO: partition the model such that v1.1 ops are not passed to v1.0 110 // device 111 LOG(ERROR) << "Could not handle prepareModel!"; 112 return ErrorStatus::GENERAL_FAILURE; 113 } 114} 115 116DeviceStatus VersionedIDevice::getStatus() { 117 if (mDeviceV1_0 == nullptr) { 118 LOG(ERROR) << "Device not available!"; 119 return DeviceStatus::UNKNOWN; 120 } 121 122 Return<DeviceStatus> ret = mDeviceV1_0->getStatus(); 123 124 if (!ret.isOk()) { 125 LOG(ERROR) << "getStatus failure: " << ret.description(); 126 return DeviceStatus::UNKNOWN; 127 } 128 return static_cast<DeviceStatus>(ret); 129} 130 131bool VersionedIDevice::operator==(nullptr_t) { 132 return mDeviceV1_0 == nullptr; 133} 134 135bool VersionedIDevice::operator!=(nullptr_t) { 136 return mDeviceV1_0 != nullptr; 137} 138 139} // namespace nn 140} // namespace android 141