Merge "Add enums for 10bit color formats"
diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h
index 0bbd803..73afe05 100644
--- a/audio/2.0/default/Stream.h
+++ b/audio/2.0/default/Stream.h
@@ -127,6 +127,7 @@
IStream::createMmapBuffer_cb _hidl_cb) {
Result retval(Result::NOT_SUPPORTED);
MmapBufferInfo info;
+ native_handle_t* hidlHandle = nullptr;
if (mStream->create_mmap_buffer != NULL) {
struct audio_mmap_buffer_info halInfo;
@@ -134,7 +135,7 @@
"create_mmap_buffer",
mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
if (retval == Result::OK) {
- native_handle_t* hidlHandle = native_handle_create(1, 0);
+ hidlHandle = native_handle_create(1, 0);
hidlHandle->data[0] = halInfo.shared_memory_fd;
info.sharedMemory = hidl_memory("audio_buffer", hidlHandle,
frameSize *halInfo.buffer_size_frames);
@@ -143,6 +144,10 @@
}
}
_hidl_cb(retval, info);
+ if (hidlHandle != nullptr) {
+ native_handle_close(hidlHandle);
+ native_handle_delete(hidlHandle);
+ }
return Void();
}
diff --git a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
index 9b7d0cf..145d4c3 100644
--- a/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
+++ b/audio/effect/2.0/vts/functional/audio_effect_hidl_hal_test.cpp
@@ -38,8 +38,7 @@
class AudioEffectHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- // currently test passthrough mode only
- effectsFactory = IEffectsFactory::getService("audio_effects_factory", true);
+ effectsFactory = IEffectsFactory::getService("audio_effects_factory");
ASSERT_NE(effectsFactory, nullptr);
}
diff --git a/biometrics/fingerprint/2.1/Android.bp b/biometrics/fingerprint/2.1/Android.bp
index 02b7328..2a252dc 100644
--- a/biometrics/fingerprint/2.1/Android.bp
+++ b/biometrics/fingerprint/2.1/Android.bp
@@ -62,3 +62,155 @@
"android.hidl.base@1.0",
],
}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint.vts.driver@2.1_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mDRIVER -tSOURCE -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "types.hal",
+ "IBiometricsFingerprint.hal",
+ "IBiometricsFingerprintClientCallback.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.cpp",
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprint.vts.cpp",
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprintClientCallback.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint.vts.driver@2.1_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mDRIVER -tHEADER -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "types.hal",
+ "IBiometricsFingerprint.hal",
+ "IBiometricsFingerprintClientCallback.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.h",
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprint.vts.h",
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprintClientCallback.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.biometrics.fingerprint.vts.driver@2.1",
+ generated_sources: ["android.hardware.biometrics.fingerprint.vts.driver@2.1_genc++"],
+ generated_headers: ["android.hardware.biometrics.fingerprint.vts.driver@2.1_genc++_headers"],
+ export_generated_headers: ["android.hardware.biometrics.fingerprint.vts.driver@2.1_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "libvts_common",
+ "libvts_datatype",
+ "libvts_measurement",
+ "libvts_multidevice_proto",
+ "libcamera_metadata",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.biometrics.fingerprint@2.1",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "IBiometricsFingerprint.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprint.vts.cpp",
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "IBiometricsFingerprint.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprint.vts.h",
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler",
+ generated_sources: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprint-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.biometrics.fingerprint@2.1",
+ ],
+}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler_genc++",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mPROFILER -tSOURCE -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "IBiometricsFingerprintClientCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprintClientCallback.vts.cpp",
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler_genc++_headers",
+ tools: ["hidl-gen", "vtsc"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lvts -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1 && $(location vtsc) -mPROFILER -tHEADER -b$(genDir) android/hardware/biometrics/fingerprint/2.1/ $(genDir)/android/hardware/biometrics/fingerprint/2.1/",
+ srcs: [
+ "IBiometricsFingerprintClientCallback.hal",
+ "types.hal",
+ ],
+ out: [
+ "android/hardware/biometrics/fingerprint/2.1/BiometricsFingerprintClientCallback.vts.h",
+ "android/hardware/biometrics/fingerprint/2.1/types.vts.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler",
+ generated_sources: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler_genc++"],
+ generated_headers: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler_genc++_headers"],
+ export_generated_headers: ["android.hardware.biometrics.fingerprint@2.1-IBiometricsFingerprintClientCallback-vts.profiler_genc++_headers"],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libvts_profiling",
+ "libvts_multidevice_proto",
+ "libprotobuf-cpp-full",
+ "android.hidl.base@1.0",
+ "android.hardware.biometrics.fingerprint@2.1",
+ ],
+}
diff --git a/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal b/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal
index 63435d1..d913cf1 100644
--- a/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal
+++ b/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal
@@ -43,8 +43,9 @@
* @param deviceId the instance of this fingerprint device
* @param fingerId the fingerprint templetate that was authenticated
* @param groupId the groupid for the template that was authenticated
+ * @param token the hardware authentication token to pass to Keystore.addAuthToken()
*/
- oneway onAuthenticated(uint64_t deviceId, uint32_t fingerId, uint32_t groupId);
+ oneway onAuthenticated(uint64_t deviceId, uint32_t fingerId, uint32_t groupId, vec<uint8_t> token);
/**
* Sent when a fingerprint error occurs
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
index 516cd00..154b7a6 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
@@ -14,10 +14,9 @@
* limitations under the License.
*/
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service"
+#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.1-service"
// For communication with Keystore binder interface
-#include <binder/IServiceManager.h>
-#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h> // for error codes
#include <hardware/hw_auth_token.h>
@@ -40,23 +39,19 @@
using RequestStatus =
android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
-sp<IBiometricsFingerprintClientCallback>
- BiometricsFingerprint::mClientCallback = nullptr;
+BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr;
-// TODO: This is here because HAL 2.1 doesn't have a way to propagate a
-// unique token for its driver. Subsequent versions should send a unique
-// token for each call to notify(). This is fine as long as there's only
-// one fingerprint device on the platform.
-fingerprint_device_t *BiometricsFingerprint::sDevice = nullptr;
-
-BiometricsFingerprint::BiometricsFingerprint(fingerprint_device_t *device)
- : mDevice(device) {
- sDevice = mDevice; // keep track of the most recent instance
+BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) {
+ sInstance = this; // keep track of the most recent instance
+ mDevice = openHal();
+ if (!mDevice) {
+ ALOGE("Can't open HAL module");
+ }
}
BiometricsFingerprint::~BiometricsFingerprint() {
- ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n");
- if (mDevice == NULL) {
+ ALOGV(LOG_VERBOSE, LOG_TAG, "~BiometricsFingerprint()\n");
+ if (mDevice == nullptr) {
ALOGE("No valid device");
return;
}
@@ -66,7 +61,7 @@
ALOGE("Can't close fingerprint module, error: %d", err);
return;
}
- mDevice = NULL;
+ mDevice = nullptr;
}
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
@@ -107,6 +102,8 @@
return FingerprintError::ERROR_CANCELED;
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
return FingerprintError::ERROR_UNABLE_TO_REMOVE;
+ case FINGERPRINT_ERROR_LOCKOUT:
+ return FingerprintError::ERROR_LOCKOUT;
default:
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
// vendor specific code.
@@ -114,7 +111,7 @@
return FingerprintError::ERROR_VENDOR;
}
}
- ALOGE("Unknown error from fingerprint vendor library");
+ ALOGE("Unknown error from fingerprint vendor library: %d", error);
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
}
@@ -143,13 +140,17 @@
return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
}
}
- ALOGE("Unknown acquiredmsg from fingerprint vendor library");
+ ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info);
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
}
Return<uint64_t> BiometricsFingerprint::setNotify(
const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
mClientCallback = clientCallback;
+ // This is here because HAL 2.1 doesn't have a way to propagate a
+ // unique token for its driver. Subsequent versions should send a unique
+ // token for each call to setNotify(). This is fine as long as there's only
+ // one fingerprint device on the platform.
return reinterpret_cast<uint64_t>(mDevice);
}
@@ -199,36 +200,44 @@
}
IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
+ if (!sInstance) {
+ sInstance = new BiometricsFingerprint();
+ }
+ return sInstance;
+}
+
+fingerprint_device_t* BiometricsFingerprint::openHal() {
int err;
- const hw_module_t *hw_mdl = NULL;
- ALOGE("Opening fingerprint hal library...");
+ const hw_module_t *hw_mdl = nullptr;
+ ALOGD("Opening fingerprint hal library...");
if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {
ALOGE("Can't open fingerprint HW Module, error: %d", err);
return nullptr;
}
- if (hw_mdl == NULL) {
+ if (hw_mdl == nullptr) {
ALOGE("No valid fingerprint module");
return nullptr;
}
fingerprint_module_t const *module =
reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
- if (module->common.methods->open == NULL) {
+ if (module->common.methods->open == nullptr) {
ALOGE("No valid open method");
return nullptr;
}
- hw_device_t *device = NULL;
+ hw_device_t *device = nullptr;
- if (0 != (err = module->common.methods->open(hw_mdl, NULL, &device))) {
+ if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) {
ALOGE("Can't open fingerprint methods, error: %d", err);
return nullptr;
}
if (kVersion != device->version) {
+ // enforce version on new devices because of HIDL@2.1 translation layer
ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
- return 0; // enforce this on new devices because of HIDL translation layer
+ return nullptr;
}
fingerprint_device_t* fp_device =
@@ -240,23 +249,67 @@
return nullptr;
}
- return new BiometricsFingerprint(fp_device);
+ return fp_device;
}
-void BiometricsFingerprint::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) {
- if (auth_token != nullptr && auth_token_length > 0) {
- // TODO: cache service?
- sp<IServiceManager> sm = android::defaultServiceManager();
- sp<::android::IBinder> binder = sm->getService(String16("android.security.keystore"));
- sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
- if (service != nullptr) {
- auto ret = service->addAuthToken(auth_token, auth_token_length);
- if (!ret.isOk()) {
- ALOGE("Failure sending auth token to KeyStore: %" PRId32, int32_t(ret));
+void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
+ BiometricsFingerprint* thisPtr = static_cast<BiometricsFingerprint*>(
+ BiometricsFingerprint::getInstance());
+ if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
+ ALOGE("Receiving callbacks before the client callback is registered.");
+ return;
+ }
+ const uint64_t devId = reinterpret_cast<uint64_t>(thisPtr->mDevice);
+ switch (msg->type) {
+ case FINGERPRINT_ERROR: {
+ int32_t vendorCode = 0;
+ FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
+ thisPtr->mClientCallback->onError(devId, result, vendorCode);
}
- } else {
- ALOGE("Unable to communicate with KeyStore");
- }
+ break;
+ case FINGERPRINT_ACQUIRED: {
+ int32_t vendorCode = 0;
+ FingerprintAcquiredInfo result =
+ VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
+ thisPtr->mClientCallback->onAcquired(devId, result, vendorCode);
+ }
+ break;
+ case FINGERPRINT_TEMPLATE_ENROLLING:
+ thisPtr->mClientCallback->onEnrollResult(devId,
+ msg->data.enroll.finger.fid,
+ msg->data.enroll.finger.gid,
+ msg->data.enroll.samples_remaining);
+ break;
+ case FINGERPRINT_TEMPLATE_REMOVED:
+ thisPtr->mClientCallback->onRemoved(devId,
+ msg->data.removed.finger.fid,
+ msg->data.removed.finger.gid,
+ msg->data.removed.remaining_templates);
+ break;
+ case FINGERPRINT_AUTHENTICATED:
+ if (msg->data.authenticated.finger.fid != 0) {
+ const uint8_t* hat =
+ reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
+ const hidl_vec<uint8_t> token(
+ std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
+ thisPtr->mClientCallback->onAuthenticated(devId,
+ msg->data.authenticated.finger.fid,
+ msg->data.authenticated.finger.gid,
+ token);
+ } else {
+ // Not a recognized fingerprint
+ thisPtr->mClientCallback->onAuthenticated(devId,
+ msg->data.authenticated.finger.fid,
+ msg->data.authenticated.finger.gid,
+ hidl_vec<uint8_t>());
+ }
+ break;
+ case FINGERPRINT_TEMPLATE_ENUMERATING:
+ thisPtr->mClientCallback->onEnumerate(devId,
+ msg->data.enumerated.finger.fid,
+ msg->data.enumerated.finger.gid,
+ msg->data.enumerated.remaining_templates);
+ break;
}
}
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
index 1f44a1c..652a3e0 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
@@ -43,7 +43,7 @@
struct BiometricsFingerprint : public IBiometricsFingerprint {
public:
- BiometricsFingerprint(fingerprint_device_t *device);
+ BiometricsFingerprint();
~BiometricsFingerprint();
// Method to wrap legacy HAL with BiometricsFingerprint class
@@ -60,68 +60,17 @@
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
- static void notify(const fingerprint_msg_t *msg) {
- if (mClientCallback == nullptr) {
- ALOGE("Receiving callbacks before the client callback is registered.");
- return;
- }
- const uint64_t devId = reinterpret_cast<uint64_t>(sDevice);
- switch (msg->type) {
- case FINGERPRINT_ERROR: {
- int32_t vendorCode = 0;
- FingerprintError result =
- VendorErrorFilter(msg->data.error, &vendorCode);
- mClientCallback->onError(devId, result, vendorCode);
- }
- break;
- case FINGERPRINT_ACQUIRED: {
- int32_t vendorCode = 0;
- FingerprintAcquiredInfo result =
- VendorAcquiredFilter(msg->data.acquired.acquired_info,
- &vendorCode);
- mClientCallback->onAcquired(devId, result, vendorCode);
- }
- break;
- case FINGERPRINT_TEMPLATE_ENROLLING:
- mClientCallback->onEnrollResult(devId,
- msg->data.enroll.finger.fid,
- msg->data.enroll.finger.gid,
- msg->data.enroll.samples_remaining);
- break;
- case FINGERPRINT_TEMPLATE_REMOVED:
- mClientCallback->onRemoved(devId,
- msg->data.removed.finger.fid,
- msg->data.removed.finger.gid,
- msg->data.removed.remaining_templates);
- break;
- case FINGERPRINT_AUTHENTICATED:
- if (msg->data.authenticated.finger.fid != 0) {
- const uint8_t* hat =
- reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
- notifyKeystore(hat, sizeof(msg->data.authenticated.hat));
- }
- mClientCallback->onAuthenticated(devId,
- msg->data.authenticated.finger.fid,
- msg->data.authenticated.finger.gid);
- break;
- case FINGERPRINT_TEMPLATE_ENUMERATING:
- mClientCallback->onEnumerate(devId,
- msg->data.enumerated.finger.fid,
- msg->data.enumerated.finger.gid,
- msg->data.enumerated.remaining_templates);
- break;
- }
- }
+
private:
- Return<RequestStatus> ErrorFilter(int32_t error);
- static void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length);
- static FingerprintError VendorErrorFilter(int32_t error,
- int32_t* vendorCode);
- static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error,
- int32_t* vendorCode);
- static sp<IBiometricsFingerprintClientCallback> mClientCallback;
+ static fingerprint_device_t* openHal();
+ static void notify(const fingerprint_msg_t *msg); /* Static callback for legacy HAL implementation */
+ static Return<RequestStatus> ErrorFilter(int32_t error);
+ static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode);
+ static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode);
+ static BiometricsFingerprint* sInstance;
+
+ sp<IBiometricsFingerprintClientCallback> mClientCallback;
fingerprint_device_t *mDevice;
- static fingerprint_device_t *sDevice; // TODO: allow multiple drivers
};
} // namespace implementation
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index 20b30ae..5f1c33f 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -16,6 +16,8 @@
#include "vendor_interface.h"
+#include <assert.h>
+
#define LOG_TAG "android.hardware.bluetooth@1.0-impl"
#include <android-base/logging.h>
#include <cutils/properties.h>
diff --git a/camera/provider/2.4/vts/functional/camera_hidl_hal_test.cpp b/camera/provider/2.4/vts/functional/camera_hidl_hal_test.cpp
index 0eb291c..0186371 100644
--- a/camera/provider/2.4/vts/functional/camera_hidl_hal_test.cpp
+++ b/camera/provider/2.4/vts/functional/camera_hidl_hal_test.cpp
@@ -95,7 +95,7 @@
void CameraHidlEnvironment::SetUp() {
// TODO: test the binderized mode
- mProvider = ICameraProvider::getService(CAMERA_PASSTHROUGH_SERVICE_NAME, true);
+ mProvider = ICameraProvider::getService(CAMERA_PASSTHROUGH_SERVICE_NAME);
// TODO: handle the device doesn't have any camera case
ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
ASSERT_NE(mProvider, nullptr);
diff --git a/contexthub/1.0/vts/Android.mk b/contexthub/1.0/vts/Android.mk
new file mode 100644
index 0000000..266884b
--- /dev/null
+++ b/contexthub/1.0/vts/Android.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+contexthub-vts-path := $(LOCAL_PATH)
+
+include $(contexthub-vts-path)/functional/vts/testcases/hal/contexthub/hidl/target/Android.mk
diff --git a/contexthub/1.0/vts/Contexthub.vts b/contexthub/1.0/vts/Contexthub.vts
new file mode 100644
index 0000000..b4e42f5
--- /dev/null
+++ b/contexthub/1.0/vts/Contexthub.vts
@@ -0,0 +1,147 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "IContexthub"
+
+package: "android.hardware.contexthub"
+
+import: "android.hardware.contexthub@1.0::IContexthubCallback"
+import: "android.hardware.contexthub@1.0::types"
+
+interface: {
+ api: {
+ name: "getHubs"
+ return_type_hidl: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::ContextHub"
+ }
+ }
+ }
+
+ api: {
+ name: "registerCallback"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_HIDL_CALLBACK
+ predefined_type: "IContexthubCallback"
+ is_callback: true
+ }
+ }
+
+ api: {
+ name: "sendMessageToHub"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::ContextHubMsg"
+ }
+ }
+
+ api: {
+ name: "loadNanoApp"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::NanoAppBinary"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+ api: {
+ name: "unloadNanoApp"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+ api: {
+ name: "enableNanoApp"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+ api: {
+ name: "disableNanoApp"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+ api: {
+ name: "queryApps"
+ return_type_hidl: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::Result"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+}
diff --git a/contexthub/1.0/vts/ContexthubCallback.vts b/contexthub/1.0/vts/ContexthubCallback.vts
new file mode 100644
index 0000000..c3784e8
--- /dev/null
+++ b/contexthub/1.0/vts/ContexthubCallback.vts
@@ -0,0 +1,61 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "IContexthubCallback"
+
+package: "android.hardware.contexthub"
+
+import: "android.hardware.contexthub@1.0::types"
+
+interface: {
+ api: {
+ name: "handleClientMsg"
+ arg: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::ContextHubMsg"
+ }
+ }
+
+ api: {
+ name: "handleTxnResult"
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ arg: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::TransactionResult"
+ }
+ }
+
+ api: {
+ name: "handleHubEvent"
+ arg: {
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::AsyncEventType"
+ }
+ }
+
+ api: {
+ name: "handleAppAbort"
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ arg: {
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ }
+
+ api: {
+ name: "handleAppsInfo"
+ arg: {
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::HubAppInfo"
+ }
+ }
+ }
+
+}
diff --git a/contexthub/1.0/vts/functional/Android.bp b/contexthub/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..e78898e
--- /dev/null
+++ b/contexthub/1.0/vts/functional/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_test {
+ name: "contexthub_hidl_hal_test",
+ gtest: true,
+ srcs: ["contexthub_hidl_hal_test.cpp"],
+ shared_libs: [
+ "liblog",
+ "libhidlbase",
+ "libhidltransport",
+ "libutils",
+ "android.hardware.contexthub@1.0",
+ ],
+ static_libs: ["libgtest"],
+ cflags: [
+ "--coverage",
+ "-O0",
+ "-g",
+ ],
+ ldflags: [
+ "--coverage",
+ ],
+}
+
diff --git a/contexthub/1.0/vts/functional/contexthub_hidl_hal_test.cpp b/contexthub/1.0/vts/functional/contexthub_hidl_hal_test.cpp
new file mode 100644
index 0000000..e4dea4f
--- /dev/null
+++ b/contexthub/1.0/vts/functional/contexthub_hidl_hal_test.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "contexthub_hidl_hal_test"
+
+#include <android-base/logging.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <android/hardware/contexthub/1.0/IContexthubCallback.h>
+#include <android/hardware/contexthub/1.0/types.h>
+#include <android/log.h>
+#include <gtest/gtest.h>
+
+#include <cinttypes>
+#include <future>
+#include <utility>
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::contexthub::V1_0::AsyncEventType;
+using ::android::hardware::contexthub::V1_0::ContextHub;
+using ::android::hardware::contexthub::V1_0::ContextHubMsg;
+using ::android::hardware::contexthub::V1_0::HubAppInfo;
+using ::android::hardware::contexthub::V1_0::IContexthub;
+using ::android::hardware::contexthub::V1_0::IContexthubCallback;
+using ::android::hardware::contexthub::V1_0::NanoAppBinary;
+using ::android::hardware::contexthub::V1_0::Result;
+using ::android::hardware::contexthub::V1_0::TransactionResult;
+using ::android::sp;
+
+#define CONTEXTHUB_SERVICE_NAME "contexthub"
+
+#define ASSERT_OK(result) ASSERT_EQ(result, Result::OK)
+#define EXPECT_OK(result) EXPECT_EQ(result, Result::OK)
+
+namespace {
+
+// App ID with vendor "GoogT" (Google Testing), app identifier 0x555555. This
+// app ID is reserved and must never appear in the list of loaded apps.
+constexpr uint64_t kNonExistentAppId = 0x476f6f6754555555;
+
+// Helper that does explicit conversion of an enum class to its underlying/base
+// type. Useful for stream output of enum values.
+template<typename EnumType>
+constexpr typename std::underlying_type<EnumType>::type asBaseType(
+ EnumType value) {
+ return static_cast<typename std::underlying_type<EnumType>::type>(value);
+}
+
+// Synchronously queries IContexthub::getHubs() and returns the result
+hidl_vec<ContextHub> getHubsSync(sp<IContexthub> hubApi) {
+ hidl_vec<ContextHub> hubList;
+ std::promise<void> barrier;
+
+ hubApi->getHubs([&hubList, &barrier](const hidl_vec<ContextHub>& hubs) {
+ hubList = hubs;
+ barrier.set_value();
+ });
+ barrier.get_future().wait_for(std::chrono::seconds(1));
+
+ return hubList;
+}
+
+// Gets a list of valid hub IDs in the system
+std::vector<uint32_t> getHubIds() {
+ static std::vector<uint32_t> hubIds;
+
+ if (hubIds.size() == 0) {
+ sp<IContexthub> hubApi = IContexthub::getService(CONTEXTHUB_SERVICE_NAME);
+
+ if (hubApi != nullptr) {
+ for (ContextHub hub : getHubsSync(hubApi)) {
+ hubIds.push_back(hub.hubId);
+ }
+ }
+ }
+
+ ALOGD("Running tests against all %zu reported hubs", hubIds.size());
+ return hubIds;
+}
+
+// Base test fixture that initializes the HAL and makes the context hub API
+// handle available
+class ContexthubHidlTestBase : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ hubApi = IContexthub::getService(CONTEXTHUB_SERVICE_NAME);
+ ASSERT_NE(hubApi, nullptr);
+
+ // getHubs() must be called at least once for proper initialization of the
+ // HAL implementation
+ getHubsSync(hubApi);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IContexthub> hubApi;
+};
+
+// Test fixture parameterized by hub ID
+class ContexthubHidlTest : public ContexthubHidlTestBase,
+ public ::testing::WithParamInterface<uint32_t> {
+ public:
+ uint32_t getHubId() {
+ return GetParam();
+ }
+
+ Result registerCallback(sp<IContexthubCallback> cb) {
+ Result result = hubApi->registerCallback(getHubId(), cb);
+ ALOGD("Registered callback, result %" PRIu32, result);
+ return result;
+ }
+};
+
+// Base callback implementation that just logs all callbacks by default
+class ContexthubCallbackBase : public IContexthubCallback {
+ public:
+ virtual Return<void> handleClientMsg(const ContextHubMsg& /*msg*/) override {
+ ALOGD("Got client message callback");
+ return Void();
+ }
+
+ virtual Return<void> handleTxnResult(
+ uint32_t txnId, TransactionResult result) override {
+ ALOGD("Got transaction result callback for txnId %" PRIu32 " with result %"
+ PRId32, txnId, result);
+ return Void();
+ }
+
+ virtual Return<void> handleHubEvent(AsyncEventType evt) override {
+ ALOGD("Got hub event callback for event type %" PRIu32, evt);
+ return Void();
+ }
+
+ virtual Return<void> handleAppAbort(uint64_t appId, uint32_t abortCode)
+ override {
+ ALOGD("Got app abort notification for appId 0x%" PRIx64 " with abort code "
+ "0x%" PRIx32, appId, abortCode);
+ return Void();
+ }
+
+ virtual Return<void> handleAppsInfo(const hidl_vec<HubAppInfo>& /*appInfo*/)
+ override {
+ ALOGD("Got app info callback");
+ return Void();
+ }
+};
+
+// Wait for a callback to occur (signaled by the given future) up to the
+// provided timeout. If the future is invalid or the callback does not come
+// within the given time, returns false.
+template<class ReturnType>
+bool waitForCallback(
+ std::future<ReturnType> future,
+ ReturnType *result,
+ std::chrono::milliseconds timeout = std::chrono::seconds(5)) {
+ auto expiration = std::chrono::system_clock::now() + timeout;
+
+ EXPECT_NE(result, nullptr);
+ EXPECT_TRUE(future.valid());
+ if (result != nullptr && future.valid()) {
+ std::future_status status = future.wait_until(expiration);
+ EXPECT_NE(status, std::future_status::timeout)
+ << "Timed out waiting for callback";
+
+ if (status == std::future_status::ready) {
+ *result = future.get();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Ensures that the metadata reported in getHubs() is sane
+TEST_F(ContexthubHidlTestBase, TestGetHubs) {
+ hidl_vec<ContextHub> hubs = getHubsSync(hubApi);
+ ALOGD("System reports %zu hubs", hubs.size());
+
+ for (ContextHub hub : hubs) {
+ ALOGD("Checking hub ID %" PRIu32, hub.hubId);
+
+ EXPECT_FALSE(hub.name.empty());
+ EXPECT_FALSE(hub.vendor.empty());
+ EXPECT_FALSE(hub.toolchain.empty());
+ EXPECT_GT(hub.peakMips, 0);
+ EXPECT_GE(hub.stoppedPowerDrawMw, 0);
+ EXPECT_GE(hub.sleepPowerDrawMw, 0);
+ EXPECT_GT(hub.peakPowerDrawMw, 0);
+
+ // Minimum 128 byte MTU as required by CHRE API v1.0
+ EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128));
+ }
+}
+
+TEST_P(ContexthubHidlTest, TestRegisterCallback) {
+ ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId());
+ ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
+}
+
+TEST_P(ContexthubHidlTest, TestRegisterNullCallback) {
+ ALOGD("TestRegisterNullCallback called, hubId %" PRIu32, getHubId());
+ ASSERT_OK(registerCallback(nullptr));
+}
+
+// Helper callback that puts the async appInfo callback data into a promise
+class QueryAppsCallback : public ContexthubCallbackBase {
+ public:
+ virtual Return<void> handleAppsInfo(const hidl_vec<HubAppInfo>& appInfo)
+ override {
+ ALOGD("Got app info callback with %zu apps", appInfo.size());
+ promise.set_value(appInfo);
+ return Void();
+ }
+
+ std::promise<hidl_vec<HubAppInfo>> promise;
+};
+
+// Calls queryApps() and checks the returned metadata
+TEST_P(ContexthubHidlTest, TestQueryApps) {
+ ALOGD("TestQueryApps called, hubId %u", getHubId());
+ sp<QueryAppsCallback> cb = new QueryAppsCallback();
+ ASSERT_OK(registerCallback(cb));
+
+ Result result = hubApi->queryApps(getHubId());
+ ASSERT_OK(result);
+
+ ALOGD("Waiting for app info callback");
+ hidl_vec<HubAppInfo> appList;
+ ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appList));
+ for (const HubAppInfo &appInfo : appList) {
+ EXPECT_NE(appInfo.appId, UINT64_C(0));
+ EXPECT_NE(appInfo.appId, kNonExistentAppId);
+ }
+}
+
+// Helper callback that puts the TransactionResult for the expectedTxnId into a
+// promise
+class TxnResultCallback : public ContexthubCallbackBase {
+ public:
+ virtual Return<void> handleTxnResult(
+ uint32_t txnId, TransactionResult result) override {
+ ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %"
+ PRIu32 ") with result %" PRId32, txnId, expectedTxnId, result);
+ if (txnId == expectedTxnId) {
+ promise.set_value(result);
+ }
+ return Void();
+ }
+
+ uint32_t expectedTxnId = 0;
+ std::promise<TransactionResult> promise;
+};
+
+// Parameterized fixture that sets the callback to TxnResultCallback
+class ContexthubTxnTest : public ContexthubHidlTest {
+ public:
+ virtual void SetUp() override {
+ ContexthubHidlTest::SetUp();
+ ASSERT_OK(registerCallback(cb));
+ }
+
+ sp<TxnResultCallback> cb = new TxnResultCallback();
+};
+
+
+// Checks cases where the hub implementation is expected to return an error, but
+// that error can be returned either synchronously or in the asynchronous
+// transaction callback. Returns an AssertionResult that can be used in
+// ASSERT/EXPECT_TRUE. Allows checking the sync result against 1 additional
+// allowed error code apart from OK and TRANSACTION_FAILED, which are always
+// allowed.
+::testing::AssertionResult checkFailureSyncOrAsync(
+ Result result, Result allowedSyncResult,
+ std::future<TransactionResult>&& future) {
+ if (result == Result::OK) {
+ // No error reported synchronously - this is OK, but then we should get an
+ // async callback with a failure status
+ TransactionResult asyncResult;
+ if (!waitForCallback(std::forward<std::future<TransactionResult>>(future),
+ &asyncResult)) {
+ return ::testing::AssertionFailure()
+ << "Got successful sync result, then failed to receive async cb";
+ } else if (asyncResult == TransactionResult::SUCCESS) {
+ return ::testing::AssertionFailure()
+ << "Got successful sync result, then unexpected successful async "
+ "result";
+ }
+ } else if (result != allowedSyncResult &&
+ result != Result::TRANSACTION_FAILED) {
+ return ::testing::AssertionFailure() << "Got sync result "
+ << asBaseType(result) << ", expected TRANSACTION_FAILED or "
+ << asBaseType(allowedSyncResult);
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+TEST_P(ContexthubTxnTest, TestSendMessageToNonExistentNanoApp) {
+ ContextHubMsg msg;
+ msg.appName = kNonExistentAppId;
+ msg.msgType = 1;
+ msg.msg.resize(4);
+ std::fill(msg.msg.begin(), msg.msg.end(), 0);
+
+ ALOGD("Sending message to non-existent nanoapp");
+ Result result = hubApi->sendMessageToHub(getHubId(), msg);
+ if (result != Result::OK &&
+ result != Result::BAD_PARAMS &&
+ result != Result::TRANSACTION_FAILED) {
+ FAIL() << "Got result " << asBaseType(result) << ", expected OK, BAD_PARAMS"
+ << ", or TRANSACTION_FAILED";
+ }
+}
+
+TEST_P(ContexthubTxnTest, TestLoadEmptyNanoApp) {
+ cb->expectedTxnId = 0123;
+ NanoAppBinary emptyApp;
+
+ emptyApp.appId = kNonExistentAppId;
+ emptyApp.appVersion = 1;
+ emptyApp.flags = 0;
+ emptyApp.targetChreApiMajorVersion = 1;
+ emptyApp.targetChreApiMinorVersion = 0;
+
+ ALOGD("Loading empty nanoapp");
+ Result result = hubApi->loadNanoApp(getHubId(), emptyApp, cb->expectedTxnId);
+ EXPECT_TRUE(checkFailureSyncOrAsync(result, Result::BAD_PARAMS,
+ cb->promise.get_future()));
+}
+
+TEST_P(ContexthubTxnTest, TestUnloadNonexistentNanoApp) {
+ cb->expectedTxnId = 1234;
+
+ ALOGD("Unloading nonexistent nanoapp");
+ Result result = hubApi->unloadNanoApp(getHubId(), kNonExistentAppId,
+ cb->expectedTxnId);
+ EXPECT_TRUE(checkFailureSyncOrAsync(result, Result::BAD_PARAMS,
+ cb->promise.get_future()));
+}
+
+TEST_P(ContexthubTxnTest, TestEnableNonexistentNanoApp) {
+ cb->expectedTxnId = 2345;
+
+ ALOGD("Enabling nonexistent nanoapp");
+ Result result = hubApi->enableNanoApp(getHubId(), kNonExistentAppId,
+ cb->expectedTxnId);
+ EXPECT_TRUE(checkFailureSyncOrAsync(result, Result::BAD_PARAMS,
+ cb->promise.get_future()));
+}
+
+TEST_P(ContexthubTxnTest, TestDisableNonexistentNanoApp) {
+ cb->expectedTxnId = 3456;
+
+ ALOGD("Disabling nonexistent nanoapp");
+ Result result = hubApi->disableNanoApp(getHubId(), kNonExistentAppId,
+ cb->expectedTxnId);
+ EXPECT_TRUE(checkFailureSyncOrAsync(result, Result::BAD_PARAMS,
+ cb->promise.get_future()));
+}
+
+// Parameterize all SingleContexthubTest tests against each valid hub ID
+INSTANTIATE_TEST_CASE_P(HubIdSpecificTests, ContexthubHidlTest,
+ ::testing::ValuesIn(getHubIds()));
+INSTANTIATE_TEST_CASE_P(HubIdSpecificTests, ContexthubTxnTest,
+ ::testing::ValuesIn(getHubIds()));
+
+} // anonymous namespace
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/Android.mk b/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/Android.mk
new file mode 100644
index 0000000..a46a0e6
--- /dev/null
+++ b/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := ContexthubHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/contexthub/hidl/target
+include test/vts/tools/build/Android.host_config.mk
diff --git a/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/AndroidTest.xml b/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..a314d1b
--- /dev/null
+++ b/contexthub/1.0/vts/functional/vts/testcases/hal/contexthub/hidl/target/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<configuration description="Config for VTS Context Hub HIDL HAL's target-side test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+ <option name="push-group" value="HidlHalTest.push" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="ContexthubHidlTargetTest" />
+ <option name="binary-test-sources" value="
+ _32bit::DATA/nativetest/contexthub_hidl_hal_test/contexthub_hidl_hal_test,
+ _64bit::DATA/nativetest64/contexthub_hidl_hal_test/contexthub_hidl_hal_test,
+ "/>
+ <option name="binary-test-type" value="gtest" />
+ <option name="binary-test-disable-framework" value="true" />
+ <option name="test-timeout" value="10m" />
+ </test>
+</configuration>
+
diff --git a/contexthub/1.0/vts/types.vts b/contexthub/1.0/vts/types.vts
new file mode 100644
index 0000000..12576b1
--- /dev/null
+++ b/contexthub/1.0/vts/types.vts
@@ -0,0 +1,475 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "types"
+
+package: "android.hardware.contexthub"
+
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::Result"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "OK"
+ scalar_value: {
+ uint32_t: 0
+ }
+ enumerator: "UNKNOWN_FAILURE"
+ scalar_value: {
+ uint32_t: 1
+ }
+ enumerator: "BAD_PARAMS"
+ scalar_value: {
+ uint32_t: 2
+ }
+ enumerator: "NOT_INIT"
+ scalar_value: {
+ uint32_t: 3
+ }
+ enumerator: "TRANSACTION_FAILED"
+ scalar_value: {
+ uint32_t: 4
+ }
+ enumerator: "TRANSACTION_PENDING"
+ scalar_value: {
+ uint32_t: 5
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::NanoAppFlags"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "SIGNED"
+ scalar_value: {
+ uint32_t: 1
+ }
+ enumerator: "ENCRYPTED"
+ scalar_value: {
+ uint32_t: 2
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::NanoAppBinary"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "appId"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "appVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "flags"
+ type: TYPE_MASK
+ predefined_type: "::android::hardware::contexthub::V1_0::NanoAppFlags"
+ }
+ struct_value: {
+ name: "targetChreApiMajorVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ struct_value: {
+ name: "targetChreApiMinorVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ struct_value: {
+ name: "customBinary"
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::SensorType"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "RESERVED"
+ scalar_value: {
+ uint32_t: 0
+ }
+ enumerator: "ACCELEROMETER"
+ scalar_value: {
+ uint32_t: 1
+ }
+ enumerator: "GYROSCOPE"
+ scalar_value: {
+ uint32_t: 2
+ }
+ enumerator: "MAGNETOMETER"
+ scalar_value: {
+ uint32_t: 3
+ }
+ enumerator: "BAROMETER"
+ scalar_value: {
+ uint32_t: 4
+ }
+ enumerator: "PROXIMITY_SENSOR"
+ scalar_value: {
+ uint32_t: 5
+ }
+ enumerator: "AMBIENT_LIGHT_SENSOR"
+ scalar_value: {
+ uint32_t: 6
+ }
+ enumerator: "STATIONARY_DETECT"
+ scalar_value: {
+ uint32_t: 7
+ }
+ enumerator: "INSTANT_MOTION_DETECT"
+ scalar_value: {
+ uint32_t: 8
+ }
+ enumerator: "GPS"
+ scalar_value: {
+ uint32_t: 256
+ }
+ enumerator: "WIFI"
+ scalar_value: {
+ uint32_t: 512
+ }
+ enumerator: "AUDIO"
+ scalar_value: {
+ uint32_t: 768
+ }
+ enumerator: "CAMERA"
+ scalar_value: {
+ uint32_t: 1024
+ }
+ enumerator: "BLE"
+ scalar_value: {
+ uint32_t: 1280
+ }
+ enumerator: "WWAN"
+ scalar_value: {
+ uint32_t: 1536
+ }
+ enumerator: "PRIVATE_SENSOR_BASE"
+ scalar_value: {
+ uint32_t: 65536
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::PhysicalSensor"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "sensorType"
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::SensorType"
+ }
+ struct_value: {
+ name: "type"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "name"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "vendor"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "version"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "fifoReservedCount"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "fifoMaxCount"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "minDelayMs"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "maxDelayMs"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "peakPowerMw"
+ type: TYPE_SCALAR
+ scalar_type: "float_t"
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::ContextHub"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "name"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "vendor"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "toolchain"
+ type: TYPE_STRING
+ }
+ struct_value: {
+ name: "platformVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "toolchainVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "hubId"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "peakMips"
+ type: TYPE_SCALAR
+ scalar_type: "float_t"
+ }
+ struct_value: {
+ name: "stoppedPowerDrawMw"
+ type: TYPE_SCALAR
+ scalar_type: "float_t"
+ }
+ struct_value: {
+ name: "sleepPowerDrawMw"
+ type: TYPE_SCALAR
+ scalar_type: "float_t"
+ }
+ struct_value: {
+ name: "peakPowerDrawMw"
+ type: TYPE_SCALAR
+ scalar_type: "float_t"
+ }
+ struct_value: {
+ name: "connectedSensors"
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::PhysicalSensor"
+ }
+ }
+ struct_value: {
+ name: "maxSupportedMsgLen"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "chrePlatformId"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "chreApiMajorVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ struct_value: {
+ name: "chreApiMinorVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ struct_value: {
+ name: "chrePatchVersion"
+ type: TYPE_SCALAR
+ scalar_type: "uint16_t"
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::HostEndPoint"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint16_t"
+
+ enumerator: "BROADCAST"
+ scalar_value: {
+ uint16_t: 65535
+ }
+ enumerator: "UNSPECIFIED"
+ scalar_value: {
+ uint16_t: 65534
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::ContextHubMsg"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "appName"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "hostEndPoint"
+ type: TYPE_SCALAR
+ scalar_type: "uint16_t"
+ }
+ struct_value: {
+ name: "msgType"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "msg"
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_SCALAR
+ scalar_type: "uint8_t"
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::HubMemoryType"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "MAIN"
+ scalar_value: {
+ uint32_t: 0
+ }
+ enumerator: "SECONDARY"
+ scalar_value: {
+ uint32_t: 1
+ }
+ enumerator: "TCM"
+ scalar_value: {
+ uint32_t: 2
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::HubMemoryFlag"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "READ"
+ scalar_value: {
+ uint32_t: 1
+ }
+ enumerator: "WRITE"
+ scalar_value: {
+ uint32_t: 2
+ }
+ enumerator: "EXEC"
+ scalar_value: {
+ uint32_t: 4
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::MemRange"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "totalBytes"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "freeBytes"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "type"
+ type: TYPE_ENUM
+ predefined_type: "::android::hardware::contexthub::V1_0::HubMemoryType"
+ }
+ struct_value: {
+ name: "flags"
+ type: TYPE_MASK
+ predefined_type: "::android::hardware::contexthub::V1_0::HubMemoryFlag"
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::AsyncEventType"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "uint32_t"
+
+ enumerator: "RESTARTED"
+ scalar_value: {
+ uint32_t: 1
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::TransactionResult"
+ type: TYPE_ENUM
+ enum_value: {
+ scalar_type: "int32_t"
+
+ enumerator: "SUCCESS"
+ scalar_value: {
+ int32_t: 0
+ }
+ enumerator: "FAILURE"
+ scalar_value: {
+ int32_t: 1
+ }
+ }
+}
+
+attribute: {
+ name: "::android::hardware::contexthub::V1_0::HubAppInfo"
+ type: TYPE_STRUCT
+ struct_value: {
+ name: "appId"
+ type: TYPE_SCALAR
+ scalar_type: "uint64_t"
+ }
+ struct_value: {
+ name: "version"
+ type: TYPE_SCALAR
+ scalar_type: "uint32_t"
+ }
+ struct_value: {
+ name: "memUsage"
+ type: TYPE_VECTOR
+ vector_value: {
+ type: TYPE_STRUCT
+ predefined_type: "::android::hardware::contexthub::V1_0::MemRange"
+ }
+ }
+ struct_value: {
+ name: "enabled"
+ type: TYPE_SCALAR
+ scalar_type: "bool_t"
+ }
+}
+
diff --git a/contexthub/Android.bp b/contexthub/Android.bp
index ba90f2c..ed19a37 100644
--- a/contexthub/Android.bp
+++ b/contexthub/Android.bp
@@ -2,4 +2,5 @@
subdirs = [
"1.0",
"1.0/default",
+ "1.0/vts/functional",
]
diff --git a/drm/1.0/default/CryptoFactory.cpp b/drm/1.0/default/CryptoFactory.cpp
index 02084e7..13cad67 100644
--- a/drm/1.0/default/CryptoFactory.cpp
+++ b/drm/1.0/default/CryptoFactory.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.drm@1.0-impl"
+
+#include <utils/Log.h>
#include "CryptoFactory.h"
#include "CryptoPlugin.h"
#include "TypeConvert.h"
-#include <utils/Log.h>
namespace android {
namespace hardware {
@@ -25,45 +27,63 @@
namespace V1_0 {
namespace implementation {
- CryptoFactory::CryptoFactory() :
- loader("/vendor/lib/mediadrm", "createCryptoFactory") {
- }
+CryptoFactory::CryptoFactory() :
+ trebleLoader("/vendor/lib/hw", "createCryptoFactory"),
+ legacyLoader("/vendor/lib/mediadrm", "createCryptoFactory") {
+}
- // Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
- Return<bool> CryptoFactory::isCryptoSchemeSupported(
- const hidl_array<uint8_t, 16>& uuid) {
- for (size_t i = 0; i < loader.factoryCount(); i++) {
- if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
- return true;
- }
- }
- return false;
- }
+// Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
+Return<bool> CryptoFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16>& uuid) {
+ return isCryptoSchemeSupported(trebleLoader, uuid) ||
+ isCryptoSchemeSupported(legacyLoader, uuid);
+}
- Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
- const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
- for (size_t i = 0; i < loader.factoryCount(); i++) {
- if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
- android::CryptoPlugin *legacyPlugin = NULL;
- status_t status = loader.getFactory(i)->createPlugin(uuid.data(),
- initData.data(), initData.size(), &legacyPlugin);
- CryptoPlugin *newPlugin = NULL;
- if (legacyPlugin == NULL) {
- ALOGE("Crypto legacy HAL: failed to create crypto plugin");
- } else {
- newPlugin = new CryptoPlugin(legacyPlugin);
+Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
+ sp<ICryptoPlugin> plugin = createTreblePlugin(uuid, initData);
+ if (plugin == nullptr) {
+ plugin = createLegacyPlugin(uuid, initData);
+ }
+ _hidl_cb(plugin != nullptr ? Status::OK : Status::ERROR_DRM_CANNOT_HANDLE, plugin);
+ return Void();
+}
+
+sp<ICryptoPlugin> CryptoFactory::createTreblePlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData) {
+ sp<ICryptoPlugin> plugin;
+ for (size_t i = 0; i < trebleLoader.factoryCount(); i++) {
+ Return<void> hResult = trebleLoader.getFactory(i)->createPlugin(uuid, initData,
+ [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
+ if (status == Status::OK) {
+ plugin = hPlugin;
+ }
}
- _hidl_cb(toStatus(status), newPlugin);
- return Void();
- }
+ );
+ if (plugin != nullptr) {
+ return plugin;
}
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
- return Void();
}
+ return nullptr;
+}
- ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* /* name */) {
- return new CryptoFactory();
+sp<ICryptoPlugin> CryptoFactory::createLegacyPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData) {
+ android::CryptoPlugin *legacyPlugin = nullptr;
+ for (size_t i = 0; i < legacyLoader.factoryCount(); i++) {
+ legacyLoader.getFactory(i)->createPlugin(uuid.data(),
+ initData.data(), initData.size(), &legacyPlugin);
+ if (legacyPlugin) {
+ return new CryptoPlugin(legacyPlugin);
+ }
}
+ return nullptr;
+}
+
+
+ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* /* name */) {
+ return new CryptoFactory();
+}
} // namespace implementation
} // namespace V1_0
diff --git a/drm/1.0/default/CryptoFactory.h b/drm/1.0/default/CryptoFactory.h
index 412b557..d774406 100644
--- a/drm/1.0/default/CryptoFactory.h
+++ b/drm/1.0/default/CryptoFactory.h
@@ -41,8 +41,7 @@
CryptoFactory();
virtual ~CryptoFactory() {}
- // Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
-
+ // Methods from ::android::hardware::drmn::V1_0::ICryptoFactory follow.
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
override;
@@ -51,7 +50,27 @@
override;
private:
- android::PluginLoader<android::CryptoFactory> loader;
+ template <typename L> Return<bool> isCryptoSchemeSupported(
+ const L& loader, const hidl_array<uint8_t, 16>& uuid) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ sp<ICryptoPlugin> createTreblePlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData);
+
+ sp<ICryptoPlugin> createLegacyPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData);
+
+ typedef android::PluginLoader<ICryptoFactory> PluginLoader;
+ PluginLoader trebleLoader;
+
+ typedef android::PluginLoader<android::CryptoFactory> LegacyLoader;
+ LegacyLoader legacyLoader;
CryptoFactory(const CryptoFactory &) = delete;
void operator=(const CryptoFactory &) = delete;
diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp
index 073f030..fb61ede 100644
--- a/drm/1.0/default/CryptoPlugin.cpp
+++ b/drm/1.0/default/CryptoPlugin.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "CryptoPlugin.h"
#include "TypeConvert.h"
@@ -61,6 +62,11 @@
const DestinationBuffer& destination,
decrypt_cb _hidl_cb) {
+ if (mSharedBufferBase == NULL) {
+ _hidl_cb(Status::BAD_VALUE, 0, "decrypt buffer base not set");
+ return Void();
+ }
+
android::CryptoPlugin::Mode legacyMode;
switch(mode) {
case Mode::UNENCRYPTED:
diff --git a/drm/1.0/default/DrmFactory.cpp b/drm/1.0/default/DrmFactory.cpp
index cba2c99..d7a7c6d 100644
--- a/drm/1.0/default/DrmFactory.cpp
+++ b/drm/1.0/default/DrmFactory.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.drm@1.0-impl"
+
+#include <utils/Log.h>
#include "DrmFactory.h"
#include "DrmPlugin.h"
#include "TypeConvert.h"
-#include <utils/Log.h>
namespace android {
namespace hardware {
@@ -25,56 +27,65 @@
namespace V1_0 {
namespace implementation {
- DrmFactory::DrmFactory() :
- loader("/vendor/lib/mediadrm", "createDrmFactory") {
+DrmFactory::DrmFactory() :
+ trebleLoader("/vendor/lib/hw", "createDrmFactory"),
+ legacyLoader("/vendor/lib/mediadrm", "createDrmFactory") {
+}
+
+// Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
+Return<bool> DrmFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16>& uuid) {
+ return isCryptoSchemeSupported(trebleLoader, uuid) ||
+ isCryptoSchemeSupported(legacyLoader, uuid);
+}
+
+Return<bool> DrmFactory::isContentTypeSupported (
+ const hidl_string& mimeType) {
+ return isContentTypeSupported<PluginLoader, hidl_string>(trebleLoader, mimeType) ||
+ isContentTypeSupported<LegacyLoader, String8>(legacyLoader, mimeType);
+}
+
+Return<void> DrmFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ createPlugin_cb _hidl_cb) {
+ sp<IDrmPlugin> plugin = createTreblePlugin(uuid);
+ if (plugin == nullptr) {
+ plugin = createLegacyPlugin(uuid);
}
+ _hidl_cb(plugin != nullptr ? Status::OK : Status::ERROR_DRM_CANNOT_HANDLE, plugin);
+ return Void();
+}
- // Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
- Return<bool> DrmFactory::isCryptoSchemeSupported (
- const hidl_array<uint8_t, 16>& uuid) {
- for (size_t i = 0; i < loader.factoryCount(); i++) {
- if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
- return true;
- }
- }
- return false;
- }
-
- Return<bool> DrmFactory::isContentTypeSupported (
- const hidl_string& mimeType) {
- for (size_t i = 0; i < loader.factoryCount(); i++) {
- if (loader.getFactory(i)->isContentTypeSupported(String8(mimeType.c_str()))) {
- return true;
- }
- }
- return false;
- }
-
- Return<void> DrmFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
- createPlugin_cb _hidl_cb) {
-
- for (size_t i = 0; i < loader.factoryCount(); i++) {
- if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
- android::DrmPlugin *legacyPlugin = NULL;
- status_t status = loader.getFactory(i)->createDrmPlugin(
- uuid.data(), &legacyPlugin);
- DrmPlugin *newPlugin = NULL;
- if (legacyPlugin == NULL) {
- ALOGE("Drm legacy HAL: failed to create drm plugin");
- } else {
- newPlugin = new DrmPlugin(legacyPlugin);
+sp<IDrmPlugin> DrmFactory::createTreblePlugin(const hidl_array<uint8_t, 16>& uuid) {
+ sp<IDrmPlugin> plugin;
+ for (size_t i = 0; i < trebleLoader.factoryCount(); i++) {
+ Return<void> hResult = trebleLoader.getFactory(i)->createPlugin(uuid,
+ [&](Status status, const sp<IDrmPlugin>& hPlugin) {
+ if (status == Status::OK) {
+ plugin = hPlugin;
+ }
}
- _hidl_cb(toStatus(status), newPlugin);
- return Void();
- }
+ );
+ if (plugin != nullptr) {
+ return plugin;
}
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
- return Void();
}
+ return nullptr;
+}
- IDrmFactory* HIDL_FETCH_IDrmFactory(const char* /* name */) {
- return new DrmFactory();
+sp<IDrmPlugin> DrmFactory::createLegacyPlugin(const hidl_array<uint8_t, 16>& uuid) {
+ android::DrmPlugin *legacyPlugin = nullptr;
+ for (size_t i = 0; i < legacyLoader.factoryCount(); i++) {
+ legacyLoader.getFactory(i)->createDrmPlugin(uuid.data(), &legacyPlugin);
+ if (legacyPlugin) {
+ return new DrmPlugin(legacyPlugin);
+ }
}
+ return nullptr;
+}
+
+IDrmFactory* HIDL_FETCH_IDrmFactory(const char* /* name */) {
+ return new DrmFactory();
+}
} // namespace implementation
} // namespace V1_0
diff --git a/drm/1.0/default/DrmFactory.h b/drm/1.0/default/DrmFactory.h
index 78b7f6e..3291ea2 100644
--- a/drm/1.0/default/DrmFactory.h
+++ b/drm/1.0/default/DrmFactory.h
@@ -42,18 +42,43 @@
virtual ~DrmFactory() {}
// Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
-
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
override;
- Return<bool> isContentTypeSupported(const hidl_string &mimeType)
+ Return<bool> isContentTypeSupported(const hidl_string& mimeType)
override;
Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
- createPlugin_cb _hidl_cb) override;
-
+ createPlugin_cb _hidl_cb) override;
private:
- android::PluginLoader<android::DrmFactory> loader;
+ template <typename L> Return<bool> isCryptoSchemeSupported(
+ const L& loader, const hidl_array<uint8_t, 16>& uuid) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <typename L, typename S> Return<bool> isContentTypeSupported(
+ const L& loader, const hidl_string& mimeType) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isContentTypeSupported(S(mimeType))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ sp<IDrmPlugin> createTreblePlugin(const hidl_array<uint8_t, 16>& uuid);
+ sp<IDrmPlugin> createLegacyPlugin(const hidl_array<uint8_t, 16>& uuid);
+
+ typedef android::PluginLoader<IDrmFactory> PluginLoader;
+ PluginLoader trebleLoader;
+
+ typedef android::PluginLoader<android::DrmFactory> LegacyLoader;
+ LegacyLoader legacyLoader;
DrmFactory(const DrmFactory &) = delete;
void operator=(const DrmFactory &) = delete;
diff --git a/drm/1.0/default/DrmPlugin.cpp b/drm/1.0/default/DrmPlugin.cpp
index 9204fc5..1b2f90e 100644
--- a/drm/1.0/default/DrmPlugin.cpp
+++ b/drm/1.0/default/DrmPlugin.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.drm@1.0-impl"
#include <utils/KeyedVector.h>
#include <utils/String8.h>
diff --git a/drm/1.0/default/TypeConvert.cpp b/drm/1.0/default/TypeConvert.cpp
index 52cc503..ede2a38 100644
--- a/drm/1.0/default/TypeConvert.cpp
+++ b/drm/1.0/default/TypeConvert.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "TypeConvert.h"
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index fba56ec..d2507c4 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#define LOG_TAG "android.hardware.drm@1.0-service"
#include <1.0/default/CryptoFactory.h>
diff --git a/evs/1.0/IEvsCamera.hal b/evs/1.0/IEvsCamera.hal
index a2fc565..d0559d7 100644
--- a/evs/1.0/IEvsCamera.hal
+++ b/evs/1.0/IEvsCamera.hal
@@ -65,7 +65,7 @@
* as one), and if the supply is exhausted, no further frames may be
* delivered until a buffer is returned.
*/
- doneWithFrame(uint32_t frameId, handle bufferHandle) generates (EvsResult result);
+ oneway doneWithFrame(BufferDesc buffer);
/**
* Stop the delivery of EVS camera frames.
diff --git a/evs/1.0/IEvsCameraStream.hal b/evs/1.0/IEvsCameraStream.hal
index ef5460f..fcd5717 100644
--- a/evs/1.0/IEvsCameraStream.hal
+++ b/evs/1.0/IEvsCameraStream.hal
@@ -32,5 +32,5 @@
* must be delivered, signifying the end of the stream. No further frame
* deliveries may happen thereafter.
*/
- oneway deliverFrame(uint32_t frameId, handle bufferHandle);
+ oneway deliverFrame(BufferDesc buffer);
};
diff --git a/evs/1.0/IEvsDisplay.hal b/evs/1.0/IEvsDisplay.hal
index a473872..8352221 100644
--- a/evs/1.0/IEvsDisplay.hal
+++ b/evs/1.0/IEvsDisplay.hal
@@ -65,7 +65,7 @@
* must be returned via a call to returnTargetBufferForDisplay() even if the
* display is no longer visible.
*/
- getTargetBuffer() generates (handle bufferHandle);
+ getTargetBuffer() generates (BufferDesc buffer);
/**
@@ -76,5 +76,5 @@
* call. The buffer may be returned at any time and in any DisplayState, but all
* buffers are expected to be returned before the IEvsDisplay interface is destroyed.
*/
- returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);
+ returnTargetBufferForDisplay(BufferDesc buffer) generates (EvsResult result);
};
diff --git a/evs/1.0/IEvsEnumerator.hal b/evs/1.0/IEvsEnumerator.hal
index e3a1382..3779866 100644
--- a/evs/1.0/IEvsEnumerator.hal
+++ b/evs/1.0/IEvsEnumerator.hal
@@ -67,5 +67,15 @@
* NOTE: All buffer must have been returned to the display before making this call.
*/
closeDisplay(IEvsDisplay display);
+
+ /**
+ * This call requests the current state of the display
+ *
+ * If there is no open display, this returns DisplayState::NOT_OPEN. otherwise, it returns
+ * the actual state of the active display. This call is replicated on the IEvsEnumerator
+ * interface in order to allow secondary clients to monitor the state of the EVS display
+ * without acquiring exclusive ownership of the display.
+ */
+ getDisplayState() generates (DisplayState state);
};
diff --git a/evs/1.0/default/Android.bp b/evs/1.0/default/Android.bp
index 3bda250..e3bff25 100644
--- a/evs/1.0/default/Android.bp
+++ b/evs/1.0/default/Android.bp
@@ -11,7 +11,6 @@
shared_libs: [
"android.hardware.evs@1.0",
- "android.hardware.graphics.allocator@2.0",
"libui",
"libbase",
"libbinder",
diff --git a/evs/1.0/default/EvsCamera.cpp b/evs/1.0/default/EvsCamera.cpp
index 6715a2e..c62f7b6 100644
--- a/evs/1.0/default/EvsCamera.cpp
+++ b/evs/1.0/default/EvsCamera.cpp
@@ -33,18 +33,22 @@
const char EvsCamera::kCameraName_Backup[] = "backup";
const char EvsCamera::kCameraName_RightTurn[] = "Right Turn";
+// Arbitrary limit on number of graphics buffers allowed to be allocated
+// Safeguards against unreasonable resource consumption and provides a testable limit
+const unsigned MAX_BUFFERS_IN_FLIGHT = 100;
+
// TODO(b/31632518): Need to get notification when our client dies so we can close the camera.
-// As it stands, if the client dies suddently, the buffer may be stranded.
-// As possible work around would be to give the client a HIDL object to exclusively hold
-// and use it's destructor to perform some work in the server side.
+// As it stands, if the client dies suddenly, the buffer may be stranded.
-EvsCamera::EvsCamera(const char *id) {
+EvsCamera::EvsCamera(const char *id) :
+ mFramesAllowed(0),
+ mFramesInUse(0),
+ mStreamState(STOPPED) {
+
ALOGD("EvsCamera instantiated");
mDescription.cameraId = id;
- mFrameBusy = false;
- mStreamState = STOPPED;
// Set up dummy data for testing
if (mDescription.cameraId == kCameraName_Backup) {
@@ -52,16 +56,23 @@
mDescription.vendorFlags = 0xFFFFFFFF; // Arbitrary value
mDescription.defaultHorResolution = 320; // 1/2 NTSC/VGA
mDescription.defaultVerResolution = 240; // 1/2 NTSC/VGA
- }
- else if (mDescription.cameraId == kCameraName_RightTurn) {
+ } else if (mDescription.cameraId == kCameraName_RightTurn) {
// Nothing but the name and the usage hint
mDescription.hints = static_cast<uint32_t>(UsageHint::USAGE_HINT_RIGHT_TURN);
- }
- else {
+ } else {
// Leave empty for a minimalist camera description without even a hint
}
+
+
+ // Set our buffer properties
+ mWidth = (mDescription.defaultHorResolution) ? mDescription.defaultHorResolution : 640;
+ mHeight = (mDescription.defaultVerResolution) ? mDescription.defaultVerResolution : 480;
+
+ mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE;
}
+
EvsCamera::~EvsCamera() {
ALOGD("EvsCamera being destroyed");
std::lock_guard<std::mutex> lock(mAccessLock);
@@ -70,11 +81,14 @@
// (It really should be already)
stopVideoStream();
- // Drop the graphics buffer we've been using
- if (mBuffer) {
- // Drop the graphics buffer we've been using
- GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- alloc.free(mBuffer);
+ // Drop all the graphics buffers we've been using
+ GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+ for (auto&& rec : mBuffers) {
+ if (rec.inUse) {
+ ALOGE("Error - releasing buffer despite remote ownership");
+ }
+ alloc.free(rec.handle);
+ rec.handle = nullptr;
}
ALOGD("EvsCamera destroyed");
@@ -95,113 +109,109 @@
ALOGD("setMaxFramesInFlight");
std::lock_guard<std::mutex> lock(mAccessLock);
- // TODO: Update our stored value
-
- // TODO: Adjust our buffer count right now if we can. Otherwise, it'll adjust in doneWithFrame
-
- // For now we support only one!
- if (bufferCount != 1) {
- return EvsResult::BUFFER_NOT_AVAILABLE;
+ // We cannot function without at least one video buffer to send data
+ if (bufferCount < 1) {
+ ALOGE("Ignoring setMaxFramesInFlight with less than one buffer requested");
+ return EvsResult::INVALID_ARG;
}
- return EvsResult::OK;
+ // Update our internal state
+ if (setAvailableFrames_Locked(bufferCount)) {
+ return EvsResult::OK;
+ } else {
+ return EvsResult::BUFFER_NOT_AVAILABLE;
+ }
}
+
Return<EvsResult> EvsCamera::startVideoStream(const ::android::sp<IEvsCameraStream>& stream) {
ALOGD("startVideoStream");
std::lock_guard<std::mutex> lock(mAccessLock);
- // We only support a single stream at a time
if (mStreamState != STOPPED) {
ALOGE("ignoring startVideoStream call when a stream is already running.");
return EvsResult::STREAM_ALREADY_RUNNING;
}
+ // If the client never indicated otherwise, configure ourselves for a single streaming buffer
+ if (mFramesAllowed < 1) {
+ if (!setAvailableFrames_Locked(1)) {
+ ALOGE("Failed to start stream because we couldn't get a graphics buffer");
+ return EvsResult::BUFFER_NOT_AVAILABLE;
+ }
+ }
+
// Record the user's callback for use when we have a frame ready
mStream = stream;
- // Allocate a graphics buffer into which we'll put our test images
- if (!mBuffer) {
- mWidth = (mDescription.defaultHorResolution) ? mDescription.defaultHorResolution : 640;
- mHeight = (mDescription.defaultVerResolution) ? mDescription.defaultVerResolution : 480;
- // TODO: What about stride? Assume no padding for now...
- mStride = 4* mWidth; // Special cased to assume 4 byte pixels with no padding for now
-
- ALOGD("Allocating buffer for camera frame");
- GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
- status_t result = alloc.allocate(mWidth, mHeight,
- HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_HW_TEXTURE,
- &mBuffer, &mStride, 0, "EvsCamera");
- if (result != NO_ERROR) {
- ALOGE("Error %d allocating %d x %d graphics buffer", result, mWidth, mHeight);
- return EvsResult::BUFFER_NOT_AVAILABLE;
- }
- if (!mBuffer) {
- ALOGE("We didn't get a buffer handle back from the allocator");
- return EvsResult::BUFFER_NOT_AVAILABLE;
- }
- }
-
// Start the frame generation thread
mStreamState = RUNNING;
- mCaptureThread = std::thread([this](){GenerateFrames();});
+ mCaptureThread = std::thread([this](){ generateFrames(); });
return EvsResult::OK;
}
-Return<EvsResult> EvsCamera::doneWithFrame(uint32_t /* frameId */, const hidl_handle& bufferHandle) {
+
+Return<void> EvsCamera::doneWithFrame(const BufferDesc& buffer) {
ALOGD("doneWithFrame");
- std::lock_guard<std::mutex> lock(mAccessLock);
-
- if (!bufferHandle)
- {
- ALOGE("ignoring doneWithFrame called with invalid handle");
- return EvsResult::INVALID_ARG;
- }
-
- // TODO: Track which frames we've delivered and validate this is one of them
-
- // Mark the frame buffer as available for a new frame
- mFrameBusy = false;
-
- // TODO: If we currently have too many buffers, drop this one
-
- return EvsResult::OK;
-}
-
-Return<void> EvsCamera::stopVideoStream() {
- ALOGD("stopVideoStream");
-
- bool waitForJoin = false;
- // Lock scope
- {
+ { // lock context
std::lock_guard <std::mutex> lock(mAccessLock);
- if (mStreamState == RUNNING) {
- // Tell the GenerateFrames loop we want it to stop
- mStreamState = STOPPING;
+ if (buffer.memHandle == nullptr) {
+ ALOGE("ignoring doneWithFrame called with null handle");
+ } else if (buffer.bufferId >= mBuffers.size()) {
+ ALOGE("ignoring doneWithFrame called with invalid bufferId %d (max is %lu)",
+ buffer.bufferId, mBuffers.size()-1);
+ } else if (!mBuffers[buffer.bufferId].inUse) {
+ ALOGE("ignoring doneWithFrame called on frame %d which is already free",
+ buffer.bufferId);
+ } else {
+ // Mark the frame as available
+ mBuffers[buffer.bufferId].inUse = false;
+ mFramesInUse--;
- // Note that we asked the thread to stop and should wait for it do so
- waitForJoin = true;
- }
- }
-
- if (waitForJoin) {
- // Block outside the mutex until the "stop" flag has been acknowledged
- // NOTE: We won't send any more frames, but the client might still get one already in flight
- ALOGD("Waiting for stream thread to end...");
- mCaptureThread.join();
-
- // Lock scope
- {
- std::lock_guard <std::mutex> lock(mAccessLock);
- mStreamState = STOPPED;
+ // If this frame's index is high in the array, try to move it down
+ // to improve locality after mFramesAllowed has been reduced.
+ if (buffer.bufferId >= mFramesAllowed) {
+ // Find an empty slot lower in the array (which should always exist in this case)
+ for (auto&& rec : mBuffers) {
+ if (rec.handle == nullptr) {
+ rec.handle = mBuffers[buffer.bufferId].handle;
+ mBuffers[buffer.bufferId].handle = nullptr;
+ break;
+ }
+ }
+ }
}
}
return Void();
}
+
+Return<void> EvsCamera::stopVideoStream() {
+ ALOGD("stopVideoStream");
+ std::unique_lock <std::mutex> lock(mAccessLock);
+
+ if (mStreamState == RUNNING) {
+ // Tell the GenerateFrames loop we want it to stop
+ mStreamState = STOPPING;
+
+ // Block outside the mutex until the "stop" flag has been acknowledged
+ // We won't send any more frames, but the client might still get some already in flight
+ ALOGD("Waiting for stream thread to end...");
+ lock.unlock();
+ mCaptureThread.join();
+ lock.lock();
+
+ mStreamState = STOPPED;
+ ALOGD("Stream marked STOPPED.");
+ }
+
+ return Void();
+}
+
+
Return<int32_t> EvsCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
ALOGD("getExtendedInfo");
std::lock_guard<std::mutex> lock(mAccessLock);
@@ -215,6 +225,7 @@
return 0;
}
+
Return<EvsResult> EvsCamera::setExtendedInfo(uint32_t /*opaqueIdentifier*/, int32_t /*opaqueValue*/) {
ALOGD("setExtendedInfo");
std::lock_guard<std::mutex> lock(mAccessLock);
@@ -224,10 +235,124 @@
}
-void EvsCamera::GenerateFrames() {
- ALOGD("Frame generate loop started");
+bool EvsCamera::setAvailableFrames_Locked(unsigned bufferCount) {
+ if (bufferCount < 1) {
+ ALOGE("Ignoring request to set buffer count to zero");
+ return false;
+ }
+ if (bufferCount > MAX_BUFFERS_IN_FLIGHT) {
+ ALOGE("Rejecting buffer request in excess of internal limit");
+ return false;
+ }
- uint32_t frameNumber;
+ // Is an increase required?
+ if (mFramesAllowed < bufferCount) {
+ // An increase is required
+ unsigned needed = bufferCount - mFramesAllowed;
+ ALOGI("Allocating %d buffers for camera frames", needed);
+
+ unsigned added = increaseAvailableFrames_Locked(needed);
+ if (added != needed) {
+ // If we didn't add all the frames we needed, then roll back to the previous state
+ ALOGE("Rolling back to previous frame queue size");
+ decreaseAvailableFrames_Locked(added);
+ return false;
+ }
+ } else if (mFramesAllowed > bufferCount) {
+ // A decrease is required
+ unsigned framesToRelease = mFramesAllowed - bufferCount;
+ ALOGI("Returning %d camera frame buffers", framesToRelease);
+
+ unsigned released = decreaseAvailableFrames_Locked(framesToRelease);
+ if (released != framesToRelease) {
+ // This shouldn't happen with a properly behaving client because the client
+ // should only make this call after returning sufficient outstanding buffers
+ // to allow a clean resize.
+ ALOGE("Buffer queue shrink failed -- too many buffers currently in use?");
+ }
+ }
+
+ return true;
+}
+
+
+unsigned EvsCamera::increaseAvailableFrames_Locked(unsigned numToAdd) {
+ // Acquire the graphics buffer allocator
+ GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
+
+ unsigned added = 0;
+
+ while (added < numToAdd) {
+ buffer_handle_t memHandle = nullptr;
+ status_t result = alloc.allocate(mWidth, mHeight,
+ mFormat, 1,
+ mUsage,
+ &memHandle, &mStride, 0, "EvsCamera");
+ if (result != NO_ERROR) {
+ ALOGE("Error %d allocating %d x %d graphics buffer", result, mWidth, mHeight);
+ break;
+ }
+ if (!memHandle) {
+ ALOGE("We didn't get a buffer handle back from the allocator");
+ break;
+ }
+
+ // Find a place to store the new buffer
+ bool stored = false;
+ for (auto&& rec : mBuffers) {
+ if (rec.handle == nullptr) {
+ // Use this existing entry
+ rec.handle = memHandle;
+ rec.inUse = false;
+ stored = true;
+ break;
+ }
+ }
+ if (!stored) {
+ // Add a BufferRecord wrapping this handle to our set of available buffers
+ mBuffers.emplace_back(memHandle);
+ }
+
+ mFramesAllowed++;
+ added++;
+ }
+
+ return added;
+}
+
+
+unsigned EvsCamera::decreaseAvailableFrames_Locked(unsigned numToRemove) {
+ // Acquire the graphics buffer allocator
+ GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
+
+ unsigned removed = 0;
+
+ for (auto&& rec : mBuffers) {
+ // Is this record not in use, but holding a buffer that we can free?
+ if ((rec.inUse == false) && (rec.handle != nullptr)) {
+ // Release buffer and update the record so we can recognize it as "empty"
+ alloc.free(rec.handle);
+ rec.handle = nullptr;
+
+ mFramesAllowed--;
+ removed++;
+
+ if (removed == numToRemove) {
+ break;
+ }
+ }
+ }
+
+ return removed;
+}
+
+
+// This is the asynchronous frame generation thread that runs in parallel with the
+// main serving thread. There is one for each active camera instance.
+void EvsCamera::generateFrames() {
+ ALOGD("Frame generation loop started");
+
+ unsigned idx;
while (true) {
bool timeForFrame = false;
@@ -235,57 +360,69 @@
{
std::lock_guard<std::mutex> lock(mAccessLock);
- // Tick the frame counter -- rollover is tolerated
- frameNumber = mFrameId++;
-
if (mStreamState != RUNNING) {
// Break out of our main thread loop
break;
}
- if (mFrameBusy) {
+ // Are we allowed to issue another buffer?
+ if (mFramesInUse >= mFramesAllowed) {
// Can't do anything right now -- skip this frame
- ALOGW("Skipped a frame because client hasn't returned a buffer\n");
- }
- else {
- // We're going to make the frame busy
- mFrameBusy = true;
- timeForFrame = true;
+ ALOGW("Skipped a frame because too many are in flight\n");
+ } else {
+ // Identify an available buffer to fill
+ for (idx = 0; idx < mBuffers.size(); idx++) {
+ if (!mBuffers[idx].inUse) {
+ if (mBuffers[idx].handle != nullptr) {
+ // Found an available record, so stop looking
+ break;
+ }
+ }
+ }
+ if (idx >= mBuffers.size()) {
+ // This shouldn't happen since we already checked mFramesInUse vs mFramesAllowed
+ ALOGE("Failed to find an available buffer slot\n");
+ } else {
+ // We're going to make the frame busy
+ mBuffers[idx].inUse = true;
+ mFramesInUse++;
+ timeForFrame = true;
+ }
}
}
if (timeForFrame) {
- // Lock our output buffer for writing
- uint32_t *pixels = nullptr;
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- mapper.lock(mBuffer,
- GRALLOC_USAGE_SW_WRITE_OFTEN,
- android::Rect(mWidth, mHeight),
- (void **) &pixels);
+ // Assemble the buffer description we'll transmit below
+ BufferDesc buff = {};
+ buff.width = mWidth;
+ buff.height = mHeight;
+ buff.stride = mStride;
+ buff.format = mFormat;
+ buff.usage = mUsage;
+ buff.bufferId = idx;
+ buff.memHandle = mBuffers[idx].handle;
- // If we failed to lock the pixel buffer, we're about to crash, but log it first
- if (!pixels) {
- ALOGE("Camera failed to gain access to image buffer for writing");
+ // Write test data into the image buffer
+ fillTestFrame(buff);
+
+ // Issue the (asynchronous) callback to the client -- can't be holding the lock
+ auto result = mStream->deliverFrame(buff);
+ if (result.isOk()) {
+ ALOGD("Delivered %p as id %d", buff.memHandle.getNativeHandle(), buff.bufferId);
+ } else {
+ // This can happen if the client dies and is likely unrecoverable.
+ // To avoid consuming resources generating failing calls, we stop sending
+ // frames. Note, however, that the stream remains in the "STREAMING" state
+ // until cleaned up on the main thread.
+ ALOGE("Frame delivery call failed in the transport layer.");
+
+ // Since we didn't actually deliver it, mark the frame as available
+ std::lock_guard<std::mutex> lock(mAccessLock);
+ mBuffers[idx].inUse = false;
+ mFramesInUse--;
+
+ break;
}
-
- // Fill in the test pixels
- for (unsigned row = 0; row < mHeight; row++) {
- for (unsigned col = 0; col < mWidth; col++) {
- // Index into the row to set the pixel at this column
- // (We're making vertical gradient in the green channel, and
- // horitzontal gradient in the blue channel)
- pixels[col] = 0xFF0000FF | ((row & 0xFF) << 16) | ((col & 0xFF) << 8);
- }
- // Point to the next row
- pixels = pixels + (mStride / sizeof(*pixels));
- }
-
- // Release our output buffer
- mapper.unlock(mBuffer);
-
- // Issue the (asynchronous) callback to the client
- mStream->deliverFrame(frameNumber, mBuffer);
- ALOGD("Delivered %p as frame %d", mBuffer, frameNumber);
}
// We arbitrarily choose to generate frames at 10 fps (1/10 * uSecPerSec)
@@ -293,11 +430,58 @@
}
// If we've been asked to stop, send one last NULL frame to signal the actual end of stream
- mStream->deliverFrame(frameNumber, nullptr);
+ BufferDesc nullBuff = {};
+ auto result = mStream->deliverFrame(nullBuff);
+ if (!result.isOk()) {
+ ALOGE("Error delivering end of stream marker");
+ }
return;
}
+
+void EvsCamera::fillTestFrame(BufferDesc buff) {
+ // Lock our output buffer for writing
+ uint32_t *pixels = nullptr;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ mapper.lock(buff.memHandle,
+ GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
+ android::Rect(buff.width, buff.height),
+ (void **) &pixels);
+
+ // If we failed to lock the pixel buffer, we're about to crash, but log it first
+ if (!pixels) {
+ ALOGE("Camera failed to gain access to image buffer for writing");
+ }
+
+ // Fill in the test pixels
+ for (unsigned row = 0; row < buff.height; row++) {
+ for (unsigned col = 0; col < buff.width; col++) {
+ // Index into the row to check the pixel at this column.
+ // We expect 0xFF in the LSB channel, a vertical gradient in the
+ // second channel, a horitzontal gradient in the third channel, and
+ // 0xFF in the MSB.
+ // The exception is the very first 32 bits which is used for the
+ // time varying frame signature to avoid getting fooled by a static image.
+ uint32_t expectedPixel = 0xFF0000FF | // MSB and LSB
+ ((row & 0xFF) << 8) | // vertical gradient
+ ((col & 0xFF) << 16); // horizontal gradient
+ if ((row | col) == 0) {
+ static uint32_t sFrameTicker = 0;
+ expectedPixel = (sFrameTicker) & 0xFF;
+ sFrameTicker++;
+ }
+ pixels[col] = expectedPixel;
+ }
+ // Point to the next row
+ pixels = pixels + (buff.stride / sizeof(*pixels));
+ }
+
+ // Release our output buffer
+ mapper.unlock(buff.memHandle);
+}
+
+
} // namespace implementation
} // namespace V1_0
} // namespace evs
diff --git a/evs/1.0/default/EvsCamera.h b/evs/1.0/default/EvsCamera.h
index 5d29125..8d644a0 100644
--- a/evs/1.0/default/EvsCamera.h
+++ b/evs/1.0/default/EvsCamera.h
@@ -23,19 +23,21 @@
#include <thread>
+
namespace android {
namespace hardware {
namespace evs {
namespace V1_0 {
namespace implementation {
+
class EvsCamera : public IEvsCamera {
public:
// Methods from ::android::hardware::evs::V1_0::IEvsCamera follow.
Return<void> getId(getId_cb id_cb) override;
Return<EvsResult> setMaxFramesInFlight(uint32_t bufferCount) override;
Return<EvsResult> startVideoStream(const ::android::sp<IEvsCameraStream>& stream) override;
- Return<EvsResult> doneWithFrame(uint32_t frameId, const hidl_handle& bufferHandle) override;
+ Return<void> doneWithFrame(const BufferDesc& buffer) override;
Return<void> stopVideoStream() override;
Return<int32_t> getExtendedInfo(uint32_t opaqueIdentifier) override;
Return<EvsResult> setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue) override;
@@ -45,34 +47,49 @@
virtual ~EvsCamera() override;
const CameraDesc& getDesc() { return mDescription; };
- void GenerateFrames();
static const char kCameraName_Backup[];
static const char kCameraName_RightTurn[];
private:
- CameraDesc mDescription = {}; // The properties of this camera
+ // These three functions are expected to be called while mAccessLock is held
+ bool setAvailableFrames_Locked(unsigned bufferCount);
+ unsigned increaseAvailableFrames_Locked(unsigned numToAdd);
+ unsigned decreaseAvailableFrames_Locked(unsigned numToRemove);
- buffer_handle_t mBuffer = nullptr; // A graphics buffer into which we'll store images
- uint32_t mWidth = 0; // number of pixels across the buffer
- uint32_t mHeight = 0; // number of pixels vertically in the buffer
- uint32_t mStride = 0; // Bytes per line in the buffer
+ void generateFrames();
+ void fillTestFrame(BufferDesc buff);
- sp<IEvsCameraStream> mStream = nullptr; // The callback the user expects when a frame is ready
+ CameraDesc mDescription = {}; // The properties of this camera
- std::thread mCaptureThread; // The thread we'll use to synthesize frames
+ std::thread mCaptureThread; // The thread we'll use to synthesize frames
- uint32_t mFrameId; // A frame counter used to identify specific frames
+ uint32_t mWidth = 0; // Horizontal pixel count in the buffers
+ uint32_t mHeight = 0; // Vertical pixel count in the buffers
+ uint32_t mFormat = 0; // Values from android_pixel_format_t [TODO: YUV? Leave opaque?]
+ uint32_t mUsage = 0; // Values from from Gralloc.h
+ uint32_t mStride = 0; // Bytes per line in the buffers
+
+ sp<IEvsCameraStream> mStream = nullptr; // The callback used to deliver each frame
+
+ struct BufferRecord {
+ buffer_handle_t handle;
+ bool inUse;
+ explicit BufferRecord(buffer_handle_t h) : handle(h), inUse(false) {};
+ };
+ std::vector<BufferRecord> mBuffers; // Graphics buffers to transfer images
+ unsigned mFramesAllowed; // How many buffers are we currently using
+ unsigned mFramesInUse; // How many buffers are currently outstanding
enum StreamStateValues {
STOPPED,
RUNNING,
STOPPING,
};
- StreamStateValues mStreamState;
- bool mFrameBusy; // A flag telling us our one buffer is in use
+ StreamStateValues mStreamState;
- std::mutex mAccessLock;
+ // Syncrhonization necessary to deconflict mCaptureThread from the main service thread
+ std::mutex mAccessLock;
};
} // namespace implementation
diff --git a/evs/1.0/default/EvsDisplay.cpp b/evs/1.0/default/EvsDisplay.cpp
index 9dba6fc..dff4c49 100644
--- a/evs/1.0/default/EvsDisplay.cpp
+++ b/evs/1.0/default/EvsDisplay.cpp
@@ -39,6 +39,7 @@
ALOGD("EvsDisplay instantiated");
// Set up our self description
+ // NOTE: These are arbitrary values chosen for testing
mInfo.displayId = "Mock Display";
mInfo.vendorFlags = 3870;
mInfo.defaultHorResolution = 320;
@@ -50,16 +51,17 @@
ALOGD("EvsDisplay being destroyed");
std::lock_guard<std::mutex> lock(mAccessLock);
- // Report if we're going away while a buffer is outstanding. This could be bad.
+ // Report if we're going away while a buffer is outstanding
if (mFrameBusy) {
- ALOGE("EvsDisplay going down while client is holding a buffer\n");
+ ALOGE("EvsDisplay going down while client is holding a buffer");
}
// Make sure we release our frame buffer
- if (mBuffer) {
+ if (mBuffer.memHandle) {
// Drop the graphics buffer we've been using
GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- alloc.free(mBuffer);
+ alloc.free(mBuffer.memHandle);
+ mBuffer.memHandle = nullptr;
}
ALOGD("EvsDisplay destroyed");
}
@@ -135,36 +137,60 @@
std::lock_guard<std::mutex> lock(mAccessLock);
// If we don't already have a buffer, allocate one now
- if (!mBuffer) {
+ if (!mBuffer.memHandle) {
+ // Assemble the buffer description we'll use for our render target
+ mBuffer.width = mInfo.defaultHorResolution;
+ mBuffer.height = mInfo.defaultVerResolution;
+ mBuffer.format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mBuffer.usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
+ mBuffer.bufferId = 0x3870; // Arbitrary magic number for self recognition
+
+ buffer_handle_t handle = nullptr;
GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- status_t result = alloc.allocate(mInfo.defaultHorResolution, mInfo.defaultVerResolution,
- HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER,
- &mBuffer, &mStride, 0, "EvsDisplay");
+ status_t result = alloc.allocate(mBuffer.width, mBuffer.height,
+ mBuffer.format, 1, mBuffer.usage,
+ &handle, &mBuffer.stride,
+ 0, "EvsDisplay");
+ if (result != NO_ERROR) {
+ ALOGE("Error %d allocating %d x %d graphics buffer",
+ result, mBuffer.width, mBuffer.height);
+ BufferDesc nullBuff = {};
+ _hidl_cb(nullBuff);
+ return Void();
+ }
+ if (!handle) {
+ ALOGE("We didn't get a buffer handle back from the allocator");
+ BufferDesc nullBuff = {};
+ _hidl_cb(nullBuff);
+ return Void();
+ }
+
+ mBuffer.memHandle = handle;
mFrameBusy = false;
- ALOGD("Allocated new buffer %p with stride %u", mBuffer, mStride);
+ ALOGD("Allocated new buffer %p with stride %u",
+ mBuffer.memHandle.getNativeHandle(), mStride);
}
// Do we have a frame available?
if (mFrameBusy) {
// This means either we have a 2nd client trying to compete for buffers
// (an unsupported mode of operation) or else the client hasn't returned
- // a previously issues buffer yet (they're behaving badly).
- // NOTE: We have to make callback even if we have nothing to provide
+ // a previously issued buffer yet (they're behaving badly).
+ // NOTE: We have to make the callback even if we have nothing to provide
ALOGE("getTargetBuffer called while no buffers available.");
- _hidl_cb(nullptr);
- }
- else {
+ BufferDesc nullBuff = {};
+ _hidl_cb(nullBuff);
+ return Void();
+ } else {
// Mark our buffer as busy
mFrameBusy = true;
// Send the buffer to the client
- ALOGD("Providing display buffer %p", mBuffer);
+ ALOGD("Providing display buffer handle %p as id %d",
+ mBuffer.memHandle.getNativeHandle(), mBuffer.bufferId);
_hidl_cb(mBuffer);
+ return Void();
}
-
- // All done
- return Void();
}
@@ -172,22 +198,19 @@
* This call tells the display that the buffer is ready for display.
* The buffer is no longer valid for use by the client after this call.
*/
-Return<EvsResult> EvsDisplay::returnTargetBufferForDisplay(const hidl_handle& bufferHandle) {
- ALOGD("returnTargetBufferForDisplay %p", bufferHandle.getNativeHandle());
+Return<EvsResult> EvsDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer) {
+ ALOGD("returnTargetBufferForDisplay %p", buffer.memHandle.getNativeHandle());
std::lock_guard<std::mutex> lock(mAccessLock);
- // This shouldn't happen if we haven't issued the buffer!
- if (!bufferHandle) {
+ // Nobody should call us with a null handle
+ if (!buffer.memHandle.getNativeHandle()) {
ALOGE ("returnTargetBufferForDisplay called without a valid buffer handle.\n");
return EvsResult::INVALID_ARG;
}
- /* TODO(b/33492405): It would be nice to validate we got back the buffer we expect,
- * but HIDL doesn't support that (yet?)
- if (bufferHandle != mBuffer) {
+ if (buffer.bufferId != mBuffer.bufferId) {
ALOGE ("Got an unrecognized frame returned.\n");
return EvsResult::INVALID_ARG;
}
- */
if (!mFrameBusy) {
ALOGE ("A frame was returned with no outstanding frames.\n");
return EvsResult::BUFFER_NOT_AVAILABLE;
@@ -204,10 +227,71 @@
if (mRequestedState != DisplayState::VISIBLE) {
// We shouldn't get frames back when we're not visible.
ALOGE ("Got an unexpected frame returned while not visible - ignoring.\n");
- }
- else {
- // Make this buffer visible
- // TODO: Add code to put this image on the screen (or validate it somehow?)
+ } else {
+ // This is where the buffer would be made visible.
+ // For now we simply validate it has the data we expect in it by reading it back
+
+ // Lock our display buffer for reading
+ uint32_t* pixels = nullptr;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ mapper.lock(mBuffer.memHandle,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
+ android::Rect(mBuffer.width, mBuffer.height),
+ (void **)&pixels);
+
+ // If we failed to lock the pixel buffer, we're about to crash, but log it first
+ if (!pixels) {
+ ALOGE("Camera failed to gain access to image buffer for reading");
+ }
+
+ // Check the test pixels
+ bool frameLooksGood = true;
+ for (unsigned row = 0; row < mInfo.defaultVerResolution; row++) {
+ for (unsigned col = 0; col < mInfo.defaultHorResolution; col++) {
+ // Index into the row to check the pixel at this column.
+ // We expect 0xFF in the LSB channel, a vertical gradient in the
+ // second channel, a horitzontal gradient in the third channel, and
+ // 0xFF in the MSB.
+ // The exception is the very first 32 bits which is used for the
+ // time varying frame signature to avoid getting fooled by a static image.
+ uint32_t expectedPixel = 0xFF0000FF | // MSB and LSB
+ ((row & 0xFF) << 8) | // vertical gradient
+ ((col & 0xFF) << 16); // horizontal gradient
+ if ((row | col) == 0) {
+ // we'll check the "uniqueness" of the frame signature below
+ continue;
+ }
+ // Walk across this row (we'll step rows below)
+ if (pixels[col] != expectedPixel) {
+ ALOGE("Pixel check mismatch in frame buffer");
+ frameLooksGood = false;
+ break;
+ }
+ }
+
+ if (!frameLooksGood) {
+ break;
+ }
+
+ // Point to the next row
+ pixels = pixels + (mStride / sizeof(*pixels));
+ }
+
+ // Ensure we don't see the same buffer twice without it being rewritten
+ static uint32_t prevSignature = ~0;
+ uint32_t signature = pixels[0] & 0xFF;
+ if (prevSignature == signature) {
+ frameLooksGood = false;
+ ALOGE("Duplicate, likely stale frame buffer detected");
+ }
+
+
+ // Release our output buffer
+ mapper.unlock(mBuffer.memHandle);
+
+ if (!frameLooksGood) {
+ return EvsResult::UNDERLYING_SERVICE_ERROR;
+ }
}
return EvsResult::OK;
diff --git a/evs/1.0/default/EvsDisplay.h b/evs/1.0/default/EvsDisplay.h
index a2d5d3e..6e0111e 100644
--- a/evs/1.0/default/EvsDisplay.h
+++ b/evs/1.0/default/EvsDisplay.h
@@ -33,7 +33,7 @@
Return<EvsResult> setDisplayState(DisplayState state) override;
Return<DisplayState> getDisplayState() override;
Return<void> getTargetBuffer(getTargetBuffer_cb _hidl_cb) override;
- Return<EvsResult> returnTargetBufferForDisplay(const hidl_handle& bufferHandle) override;
+ Return<EvsResult> returnTargetBufferForDisplay(const BufferDesc& buffer) override;
// Implementation details
EvsDisplay();
@@ -41,10 +41,10 @@
private:
DisplayDesc mInfo = {};
- buffer_handle_t mBuffer = nullptr; // A graphics buffer into which we'll store images
- uint32_t mStride = 0; // Bytes per line in the buffer
+ BufferDesc mBuffer = {}; // A graphics buffer into which we'll store images
+ uint32_t mStride = 0; // Bytes per line in the buffer
- bool mFrameBusy = false; // A flag telling us our buffer is in use
+ bool mFrameBusy = false; // A flag telling us our buffer is in use
DisplayState mRequestedState = DisplayState::NOT_VISIBLE;
std::mutex mAccessLock;
diff --git a/evs/1.0/default/EvsEnumerator.cpp b/evs/1.0/default/EvsEnumerator.cpp
index ba8da00..4bf77f3 100644
--- a/evs/1.0/default/EvsEnumerator.cpp
+++ b/evs/1.0/default/EvsEnumerator.cpp
@@ -27,6 +27,11 @@
namespace implementation {
+// TODO(b/31632518): Need to get notification when our client dies so we can close the camera.
+// As it stands, if the client dies suddenly, the camera will be stuck "open".
+// NOTE: Display should already be safe by virtue of holding only a weak pointer.
+
+
EvsEnumerator::EvsEnumerator() {
ALOGD("EvsEnumerator created");
@@ -78,15 +83,11 @@
if (!pRecord) {
ALOGE("Requested camera %s not found", cameraId.c_str());
return nullptr;
- }
- else if (pRecord->inUse) {
+ } else if (pRecord->inUse) {
ALOGE("Cannot open camera %s which is already in use", cameraId.c_str());
return nullptr;
- }
- else {
- /* TODO(b/33492405): Do this, When HIDL can give us back a recognizable pointer
+ } else {
pRecord->inUse = true;
- */
return(pRecord->pCamera);
}
}
@@ -96,14 +97,21 @@
if (camera == nullptr) {
ALOGE("Ignoring call to closeCamera with null camera pointer");
- }
- else {
- // Make sure the camera has stopped streaming
- camera->stopVideoStream();
+ } else {
+ // Find this camera in our list
+ auto it = std::find_if(mCameraList.begin(),
+ mCameraList.end(),
+ [camera](const CameraRecord& rec) {
+ return (rec.pCamera == camera);
+ });
+ if (it == mCameraList.end()) {
+ ALOGE("Ignoring close on unrecognized camera");
+ } else {
+ // Make sure the camera has stopped streaming
+ camera->stopVideoStream();
- /* TODO(b/33492405): Do this, When HIDL can give us back a recognizable pointer
- pRecord->inUse = false;
- */
+ it->inUse = false;
+ }
}
return Void();
@@ -113,41 +121,49 @@
ALOGD("openDisplay");
// If we already have a display active, then this request must be denied
- if (mActiveDisplay != nullptr) {
+ sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
+ if (pActiveDisplay != nullptr) {
ALOGW("Rejecting openDisplay request the display is already in use.");
return nullptr;
- }
- else {
+ } else {
// Create a new display interface and return it
- mActiveDisplay = new EvsDisplay();
- ALOGD("Returning new EvsDisplay object %p", mActiveDisplay.get());
- return mActiveDisplay;
+ pActiveDisplay = new EvsDisplay();
+ mActiveDisplay = pActiveDisplay;
+ ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
+ return pActiveDisplay;
}
}
Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay>& display) {
ALOGD("closeDisplay");
- if (mActiveDisplay == nullptr) {
- ALOGE("Ignoring closeDisplay when display is not active");
- }
- else if (display == nullptr) {
- ALOGE("Ignoring closeDisplay with null display pointer");
- }
- else {
+ // Do we still have a display object we think should be active?
+ sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
+
+ if (pActiveDisplay == nullptr) {
+ ALOGE("Ignoring closeDisplay when there is no active display.");
+ } else if (display != pActiveDisplay) {
+ ALOGE("Ignoring closeDisplay on a display we didn't issue");
+ ALOGI("Got %p while active display is %p.", display.get(), pActiveDisplay.get());
+ } else {
// Drop the active display
- // TODO(b/33492405): When HIDL provides recognizable pointers, add validation here.
mActiveDisplay = nullptr;
}
return Void();
}
+Return<DisplayState> EvsEnumerator::getDisplayState() {
+ ALOGD("getDisplayState");
-// TODO(b/31632518): Need to get notification when our client dies so we can close the camera.
-// As possible work around would be to give the client a HIDL object to exclusively hold
-// and use it's destructor to perform some work in the server side.
-
+ // Do we still have a display object we think should be active?
+ sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
+ if (pActiveDisplay != nullptr) {
+ return pActiveDisplay->getDisplayState();
+ } else {
+ return DisplayState::NOT_OPEN;
+ }
+}
} // namespace implementation
} // namespace V1_0
diff --git a/evs/1.0/default/EvsEnumerator.h b/evs/1.0/default/EvsEnumerator.h
index 90df837..0e719bd 100644
--- a/evs/1.0/default/EvsEnumerator.h
+++ b/evs/1.0/default/EvsEnumerator.h
@@ -38,6 +38,7 @@
Return<void> closeCamera(const ::android::sp<IEvsCamera>& carCamera) override;
Return<sp<IEvsDisplay>> openDisplay() override;
Return<void> closeDisplay(const ::android::sp<IEvsDisplay>& display) override;
+ Return<DisplayState> getDisplayState() override;
// Implementation details
EvsEnumerator();
@@ -50,7 +51,7 @@
};
std::list<CameraRecord> mCameraList;
- sp<IEvsDisplay> mActiveDisplay;
+ wp<IEvsDisplay> mActiveDisplay; // Weak pointer -> object destructs if client dies
};
} // namespace implementation
diff --git a/evs/1.0/types.hal b/evs/1.0/types.hal
index fd9dcdc..6b580cf 100644
--- a/evs/1.0/types.hal
+++ b/evs/1.0/types.hal
@@ -72,6 +72,29 @@
/*
+ * Structure representing an image buffer through our APIs
+ *
+ * In addition to the handle to the graphics memory, we need to retain
+ * the properties of the buffer for easy reference and reconstruction of
+ * an ANativeWindowBuffer object on the remote side of API calls.
+ * (Not least because OpenGL expect an ANativeWindowBuffer* for us as a
+ * texture via eglCreateImageKHR().
+ * See also related types from android.hardware.graphics.common
+ * TODO: b/34722508 Review details of interaction of this structure with gralloc and OpenGL.
+ * Specifically consider if format and/or usage should become enumerated types.
+ */
+struct BufferDesc {
+ uint32_t width; // Units of pixels
+ uint32_t height; // Units of pixels
+ uint32_t stride; // Units of bytes
+ uint32_t format; // May contain values from android_pixel_format_t
+ uint32_t usage; // May contain values from from Gralloc.h
+ uint32_t bufferId; // Opaque value from driver
+ handle memHandle; // gralloc memory buffer handle
+};
+
+
+/*
* States for control of the EVS display
*
* The DisplayInfo structure describes the basic properties of an EVS display. Any EVS
@@ -81,7 +104,8 @@
* presentation device.
*/
enum DisplayState : uint32_t {
- NOT_VISIBLE = 0, // Display is inhibited
+ NOT_OPEN = 0, // Display has not been requested by any application
+ NOT_VISIBLE, // Display is inhibited
VISIBLE_ON_NEXT_FRAME, // Will become visible with next frame
VISIBLE, // Display is currently active
NUM_STATES // Must be last
@@ -94,4 +118,5 @@
INVALID_ARG,
STREAM_ALREADY_RUNNING,
BUFFER_NOT_AVAILABLE,
+ UNDERLYING_SERVICE_ERROR,
};
\ No newline at end of file
diff --git a/gatekeeper/1.0/vts/Android.mk b/gatekeeper/1.0/vts/Android.mk
new file mode 100644
index 0000000..58c2dca
--- /dev/null
+++ b/gatekeeper/1.0/vts/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 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.
+
+
+LOCAL_PATH := $(call my-dir)
+
+include $(LOCAL_PATH)/functional/vts/testcases/hal/gatekeeper/hidl/Android.mk
diff --git a/gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp b/gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp
index 09690f8..67b4482 100644
--- a/gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp
+++ b/gatekeeper/1.0/vts/functional/gatekeeper_hidl_hal_test.cpp
@@ -187,7 +187,7 @@
GatekeeperHidlTest() : uid_(0) {}
virtual void SetUp() override {
GatekeeperResponse rsp;
- gatekeeper_ = IGatekeeper::getService("gatekeeper", false);
+ gatekeeper_ = IGatekeeper::getService("gatekeeper");
ASSERT_NE(nullptr, gatekeeper_.get());
doDeleteAllUsers(rsp);
}
diff --git a/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/Android.mk b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/gatekeeper/1.0/vts/functional/vts/testcases/hal/gatekeeper/hidl/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/gnss/1.0/IAGnss.hal b/gnss/1.0/IAGnss.hal
index 2cce519..b8f5746 100644
--- a/gnss/1.0/IAGnss.hal
+++ b/gnss/1.0/IAGnss.hal
@@ -22,6 +22,7 @@
* Extended interface for AGNSS support.
*/
interface IAGnss {
+ @export(name="", value_prefix="APN_IP_")
enum ApnIpType : uint8_t {
INVALID = 0,
IPV4 = 1,
diff --git a/gnss/1.0/IAGnssCallback.hal b/gnss/1.0/IAGnssCallback.hal
index 1984725..fe2e101 100644
--- a/gnss/1.0/IAGnssCallback.hal
+++ b/gnss/1.0/IAGnssCallback.hal
@@ -19,11 +19,13 @@
/** Callback structure for the AGNSS interface. */
interface IAGnssCallback {
/** AGNSS type **/
+ @export(name="", value_prefix="AGPS_")
enum AGnssType : uint8_t {
TYPE_SUPL = 1,
TYPE_C2K = 2
};
+ @export(name="", value_prefix="GNSS_")
enum AGnssStatusValue : uint8_t {
/** GNSS requests data connection for AGNSS. */
REQUEST_AGNSS_DATA_CONN = 1,
@@ -40,6 +42,7 @@
/*
* Represents the status of AGNSS augmented to support IPv4.
*/
+ @export(name="", value_prefix="GPS_")
struct AGnssStatusIpV4 {
AGnssType type;
AGnssStatusValue status;
diff --git a/gnss/1.0/IAGnssRil.hal b/gnss/1.0/IAGnssRil.hal
index 499b874..6292273 100644
--- a/gnss/1.0/IAGnssRil.hal
+++ b/gnss/1.0/IAGnssRil.hal
@@ -25,12 +25,14 @@
* location, unique subscriber ID, phone number string and network availability changes.
*/
interface IAGnssRil {
+ @export(name="", value_prefix="AGPS_SETID_TYPE_")
enum SetIDType : uint8_t {
NONE = 0,
IMSI = 1,
MSISDM = 2
};
+ @export(name="", value_prefix="AGPS_RIL_NETWORK_TYPE_")
enum NetworkType : uint8_t {
MOBILE = 0,
WIFI = 1,
@@ -41,6 +43,7 @@
WIMAX = 6,
};
+ @export(name="", value_prefix="AGPS_REF_LOCATION_TYPE_")
enum AGnssRefLocationType : uint8_t {
GSM_CELLID = 1,
UMTS_CELLID = 2,
diff --git a/gnss/1.0/IAGnssRilCallback.hal b/gnss/1.0/IAGnssRilCallback.hal
index ba29bd0..2d64e54 100644
--- a/gnss/1.0/IAGnssRilCallback.hal
+++ b/gnss/1.0/IAGnssRilCallback.hal
@@ -22,6 +22,7 @@
*/
interface IAGnssRilCallback {
/* Kinds of SET ID that can be requested */
+ @export(name="", value_prefix="AGPS_RIL_REQUEST_SETID_")
enum ID : uint32_t {
IMSI = 1 << 0L,
MSISDN = 1 << 1L,
diff --git a/gnss/1.0/IGnss.hal b/gnss/1.0/IGnss.hal
index 24a5371..5cde79e 100644
--- a/gnss/1.0/IGnss.hal
+++ b/gnss/1.0/IGnss.hal
@@ -28,9 +28,10 @@
import IGnssNi;
import IGnssXtra;
-/* Represents the standard GNSS interface. */
+/* Represents the standard GNSS (Global Navigation Satellite System) interface. */
interface IGnss {
/* Requested operational mode for GNSS operation. */
+ @export(name="", value_prefix="GPS_POSITION_MODE_")
enum GnssPositionMode : uint8_t {
/** Mode for running GNSS standalone (no assistance). */
STANDALONE = 0,
@@ -44,6 +45,7 @@
};
/* Requested recurrence mode for GNSS operation. */
+ @export(name="", value_prefix="GPS_POSITION_")
enum GnssPositionRecurrence : uint32_t {
/** Receive GNSS fixes on a recurring basis at a specified period. */
RECURRENCE_PERIODIC = 0,
@@ -55,6 +57,7 @@
* Flags used to specify which aiding data to delete when calling
* deleteAidingData().
*/
+ @export(name="", value_prefix="GPS_")
enum GnssAidingData : uint16_t {
DELETE_EPHEMERIS = 0x0001,
DELETE_ALMANAC = 0x0002,
diff --git a/gnss/1.0/IGnssBatching.hal b/gnss/1.0/IGnssBatching.hal
index 4f0695d..4d5affa 100644
--- a/gnss/1.0/IGnssBatching.hal
+++ b/gnss/1.0/IGnssBatching.hal
@@ -42,6 +42,7 @@
/*
* Enum which holds the bit masks for batching control.
*/
+ @export(name="", value_prefix="FLP_BATCH_")
enum Flag : uint8_t {
/*
* If this flag is set, the hardware implementation
diff --git a/gnss/1.0/IGnssCallback.hal b/gnss/1.0/IGnssCallback.hal
index afef55f..0c3b9f0 100644
--- a/gnss/1.0/IGnssCallback.hal
+++ b/gnss/1.0/IGnssCallback.hal
@@ -23,6 +23,7 @@
*/
interface IGnssCallback {
/* Flags for the gnssSetCapabilities callback. */
+ @export(name="", value_prefix="GPS_CAPABILITY_")
enum Capabilities : uint32_t {
/*
* GNSS HAL schedules fixes for RECURRENCE_PERIODIC mode.
@@ -47,6 +48,7 @@
};
/* GNSS status event values. */
+ @export(name="", value_prefix="GPS_STATUS_")
enum GnssStatusValue : uint8_t {
/** GNSS status unknown. */
NONE = 0,
@@ -63,6 +65,7 @@
/*
* Flags that indicate information about the satellite
*/
+ @export(name="", value_prefix="GNSS_SV_FLAGS_")
enum GnssSvFlags : uint8_t {
NONE = 0,
HAS_EPHEMERIS_DATA = 1 << 0,
diff --git a/gnss/1.0/IGnssGeofenceCallback.hal b/gnss/1.0/IGnssGeofenceCallback.hal
index 5c70c5e..722317e 100644
--- a/gnss/1.0/IGnssGeofenceCallback.hal
+++ b/gnss/1.0/IGnssGeofenceCallback.hal
@@ -91,17 +91,20 @@
*/
interface IGnssGeofenceCallback {
+ @export(name="", value_prefix="GPS_GEOFENCE_")
enum GeofenceTransition : int32_t {
ENTERED = (1 << 0L),
EXITED = (1 << 1L),
UNCERTAIN = (1 << 2L),
};
+ @export(name="", value_prefix="GPS_GEOFENCE_")
enum GeofenceAvailability : int32_t {
UNAVAILABLE = (1 << 0L),
AVAILABLE = (1 << 1L),
};
+ @export(name="", value_prefix="GPS_GEOFENCE_")
enum GeofenceStatus : int32_t {
OPERATION_SUCCESS = 0,
ERROR_TOO_MANY_GEOFENCES = -100,
diff --git a/gnss/1.0/IGnssMeasurement.hal b/gnss/1.0/IGnssMeasurement.hal
index 5174273..8329442 100644
--- a/gnss/1.0/IGnssMeasurement.hal
+++ b/gnss/1.0/IGnssMeasurement.hal
@@ -22,6 +22,7 @@
* Extended interface for GNSS Measurements support.
*/
interface IGnssMeasurement {
+ @export(name="", value_prefix="GPS_MEASUREMENT_")
enum GnssMeasurementStatus : int32_t {
SUCCESS = 0,
ERROR_ALREADY_INIT = -100,
diff --git a/gnss/1.0/IGnssMeasurementCallback.hal b/gnss/1.0/IGnssMeasurementCallback.hal
index 00e57cd..5789621 100644
--- a/gnss/1.0/IGnssMeasurementCallback.hal
+++ b/gnss/1.0/IGnssMeasurementCallback.hal
@@ -21,6 +21,7 @@
/*
* Flags to indicate what fields in GnssClock are valid.
*/
+ @export(name="", value_prefix="GNSS_CLOCK_")
enum GnssClockFlags : uint16_t {
/** A valid 'leap second' is stored in the data structure. */
HAS_LEAP_SECOND = 1 << 0,
@@ -41,6 +42,7 @@
/*
* Flags to indicate what fields in GnssMeasurement are valid.
*/
+ @export(name="", value_prefix="GNSS_MEASUREMENT_")
enum GnssMeasurementFlags : uint32_t {
/** A valid 'snr' is stored in the data structure. */
HAS_SNR = 1 << 0,
@@ -60,6 +62,7 @@
* Enumeration of available values for the GNSS Measurement's multipath
* indicator.
*/
+ @export(name="", value_prefix="GNSS_MULTIPATH_")
enum GnssMultipathIndicator : uint8_t {
/** The indicator is not available or unknown. */
INDICATOR_UNKNOWN = 0,
@@ -82,6 +85,7 @@
* If GNSS is still searching for a satellite, the corresponding state must be
* set to STATE_UNKNOWN(0).
*/
+ @export(name="", value_prefix="GNSS_MEASUREMENT_")
enum GnssMeasurementState : uint32_t {
STATE_UNKNOWN = 0,
STATE_CODE_LOCK = 1 << 0,
@@ -105,6 +109,7 @@
/*
* Flags indicating the Accumulated Delta Range's states.
*/
+ @export(name="", value_prefix="GNSS_")
enum GnssAccumulatedDeltaRangeState : uint16_t {
ADR_STATE_UNKNOWN = 0,
ADR_STATE_VALID = 1 << 0,
diff --git a/gnss/1.0/IGnssNavigationMessage.hal b/gnss/1.0/IGnssNavigationMessage.hal
index 11f2096..ddd9169 100644
--- a/gnss/1.0/IGnssNavigationMessage.hal
+++ b/gnss/1.0/IGnssNavigationMessage.hal
@@ -22,6 +22,7 @@
* Extended interface for GNSS navigation message reporting support.
*/
interface IGnssNavigationMessage {
+ @export(name="", value_prefix="GPS_NAVIGATION_MESSAGE_")
enum GnssNavigationMessageStatus : int32_t {
SUCCESS = 0,
ERROR_ALREADY_INIT = -100,
diff --git a/gnss/1.0/IGnssNavigationMessageCallback.hal b/gnss/1.0/IGnssNavigationMessageCallback.hal
index 0cffa67..2e6b853 100644
--- a/gnss/1.0/IGnssNavigationMessageCallback.hal
+++ b/gnss/1.0/IGnssNavigationMessageCallback.hal
@@ -25,6 +25,7 @@
* For convenience, first byte is the GnssConstellationType on which that signal
* is typically transmitted.
*/
+ @export(name="", value_prefix="GNSS_NAVIGATION_MESSAGE_TYPE_")
enum GnssNavigationMessageType : int16_t {
UNKNOWN = 0,
/** GNSS L1 C/A message contained in the structure. */
@@ -56,6 +57,7 @@
* No need to send any navigation message that contains words with parity error
* and cannot be corrected.
*/
+ @export(name="navigation_message_status", value_prefix="NAV_MESSAGE_STATUS_")
enum NavigationMessageStatus : uint16_t {
PARITY_PASSED = (1 << 0),
PARITY_REBUILT = (1 << 1),
diff --git a/gnss/1.0/IGnssNiCallback.hal b/gnss/1.0/IGnssNiCallback.hal
index a7abad9..c5fb223 100644
--- a/gnss/1.0/IGnssNiCallback.hal
+++ b/gnss/1.0/IGnssNiCallback.hal
@@ -21,6 +21,7 @@
/*
* GnssNiType constants
*/
+ @export(name="", value_prefix="GPS_NI_TYPE_")
enum GnssNiType : uint8_t {
VOICE = 1,
UMTS_SUPL = 2,
@@ -30,6 +31,7 @@
/*
* GnssNiNotifyFlags constants
*/
+ @export(name="", value_prefix="GPS_NI_")
enum GnssNiNotifyFlags : uint32_t {
/** NI requires notification */
NEED_NOTIFY = 0x0001,
@@ -43,6 +45,7 @@
* GNSS NI responses, used to define the response in
* NI structures
*/
+ @export(name="", value_prefix="GPS_NI_")
enum GnssUserResponseType : uint8_t {
RESPONSE_ACCEPT = 1,
RESPONSE_DENY = 2,
@@ -52,6 +55,7 @@
/*
* NI data encoding scheme
*/
+ @export(name="", value_prefix="GPS_")
enum GnssNiEncodingType : int32_t {
ENC_NONE = 0,
ENC_SUPL_GSM_DEFAULT = 1,
diff --git a/gnss/1.0/types.hal b/gnss/1.0/types.hal
index 2721d44..d5e0e9b 100644
--- a/gnss/1.0/types.hal
+++ b/gnss/1.0/types.hal
@@ -16,6 +16,7 @@
package android.hardware.gnss@1.0;
+@export(name="", value_prefix="GNSS_MAX_")
enum GnssMax : uint32_t {
/** Maximum number of SVs for gnssSvStatusCb(). */
SVS_COUNT = 64,
@@ -27,6 +28,8 @@
/*
* Constellation type of GnssSvInfo
*/
+
+@export(name="", value_prefix="GNSS_CONSTELLATION_")
enum GnssConstellationType : uint8_t {
UNKNOWN = 0,
GPS = 1,
@@ -38,6 +41,7 @@
};
/** Bit mask to indicate which values are valid in a GnssLocation object. */
+@export(name="", value_prefix="GPS_LOCATION_")
enum GnssLocationFlags : uint16_t {
/** GnssLocation has valid latitude and longitude. */
HAS_LAT_LONG = 0x0001,
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index da36a60..7663701 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -332,6 +332,7 @@
* -------------------------------+-----------------------------------------
* HAL_DATASPACE_JFIF | An encoded JPEG image
* HAL_DATASPACE_DEPTH | An android_depth_points buffer
+ * HAL_DATASPACE_SENSOR | Sensor event data.
* Other | Unsupported
*
*/
@@ -1090,7 +1091,17 @@
* The point cloud will be represented with the android_depth_points
* structure.
*/
- DEPTH = 0x1000
+ DEPTH = 0x1000,
+
+
+ /*
+ * The buffer contains sensor events from sensor direct report.
+ * This value is valid with formats:
+ * HAL_PIXEL_FORMAT_BLOB: an array of sensor event structure that forms
+ * a lock free queue. Format of sensor event structure is specified
+ * in Sensors HAL.
+ */
+ SENSOR = 0x1001
};
/*
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 0d63c3c..a366fa2 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -1,7 +1,28 @@
+cc_library_static {
+ name: "libhwcomposer-client",
+ export_include_dirs: ["."],
+ srcs: ["ComposerClient.cpp"],
+ cppflags: ["-DBINDERIZED"],
+ shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.composer@2.1",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libsync",
+ "libutils",
+ ],
+}
+
cc_library_shared {
name: "android.hardware.graphics.composer@2.1-impl",
relative_install_path: "hw",
- srcs: ["Hwc.cpp", "HwcClient.cpp"],
+ srcs: ["Hwc.cpp", "ComposerClient.cpp"],
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
@@ -21,10 +42,13 @@
cc_binary {
name: "android.hardware.graphics.composer@2.1-service",
relative_install_path: "hw",
- srcs: ["service.cpp", "Hwc.cpp", "HwcClient.cpp"],
+ srcs: ["service.cpp", "Hwc.cpp"],
cppflags: ["-DBINDERIZED"],
init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
+ static_libs: [
+ "libhwcomposer-client",
+ ],
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
diff --git a/graphics/composer/2.1/default/ComposerBase.h b/graphics/composer/2.1/default/ComposerBase.h
new file mode 100644
index 0000000..85b1a4d
--- /dev/null
+++ b/graphics/composer/2.1/default/ComposerBase.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
+#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <hardware/hwcomposer2.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::common::V1_0::Dataspace;
+using android::hardware::graphics::common::V1_0::ColorMode;
+using android::hardware::graphics::common::V1_0::ColorTransform;
+using android::hardware::graphics::common::V1_0::Hdr;
+
+class ComposerBase {
+public:
+ virtual ~ComposerBase() {};
+
+ virtual void removeClient() = 0;
+ virtual void enableCallback(bool enable) = 0;
+ virtual uint32_t getMaxVirtualDisplayCount() = 0;
+ virtual Error createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay) = 0;
+ virtual Error destroyVirtualDisplay(Display display) = 0;
+ virtual Error createLayer(Display display, Layer* outLayer) = 0;
+ virtual Error destroyLayer(Display display, Layer layer) = 0;
+
+ virtual Error getActiveConfig(Display display, Config* outConfig) = 0;
+ virtual Error getClientTargetSupport(Display display,
+ uint32_t width, uint32_t height,
+ PixelFormat format, Dataspace dataspace) = 0;
+ virtual Error getColorModes(Display display,
+ hidl_vec<ColorMode>* outModes) = 0;
+ virtual Error getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue) = 0;
+ virtual Error getDisplayConfigs(Display display,
+ hidl_vec<Config>* outConfigs) = 0;
+ virtual Error getDisplayName(Display display, hidl_string* outName) = 0;
+ virtual Error getDisplayType(Display display,
+ IComposerClient::DisplayType* outType) = 0;
+ virtual Error getDozeSupport(Display display, bool* outSupport) = 0;
+ virtual Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) = 0;
+
+ virtual Error setActiveConfig(Display display, Config config) = 0;
+ virtual Error setColorMode(Display display, ColorMode mode) = 0;
+ virtual Error setPowerMode(Display display,
+ IComposerClient::PowerMode mode) = 0;
+ virtual Error setVsyncEnabled(Display display,
+ IComposerClient::Vsync enabled) = 0;
+
+ virtual Error setColorTransform(Display display, const float* matrix,
+ int32_t hint) = 0;
+ virtual Error setClientTarget(Display display, buffer_handle_t target,
+ int32_t acquireFence, int32_t dataspace,
+ const std::vector<hwc_rect_t>& damage) = 0;
+ virtual Error setOutputBuffer(Display display, buffer_handle_t buffer,
+ int32_t releaseFence) = 0;
+ virtual Error validateDisplay(Display display,
+ std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask,
+ std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks) = 0;
+ virtual Error acceptDisplayChanges(Display display) = 0;
+ virtual Error presentDisplay(Display display, int32_t* outPresentFence,
+ std::vector<Layer>* outLayers,
+ std::vector<int32_t>* outReleaseFences) = 0;
+
+ virtual Error setLayerCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y) = 0;
+ virtual Error setLayerBuffer(Display display, Layer layer,
+ buffer_handle_t buffer, int32_t acquireFence) = 0;
+ virtual Error setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& damage) = 0;
+ virtual Error setLayerBlendMode(Display display, Layer layer,
+ int32_t mode) = 0;
+ virtual Error setLayerColor(Display display, Layer layer,
+ IComposerClient::Color color) = 0;
+ virtual Error setLayerCompositionType(Display display, Layer layer,
+ int32_t type) = 0;
+ virtual Error setLayerDataspace(Display display, Layer layer,
+ int32_t dataspace) = 0;
+ virtual Error setLayerDisplayFrame(Display display, Layer layer,
+ const hwc_rect_t& frame) = 0;
+ virtual Error setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha) = 0;
+ virtual Error setLayerSidebandStream(Display display, Layer layer,
+ buffer_handle_t stream) = 0;
+ virtual Error setLayerSourceCrop(Display display, Layer layer,
+ const hwc_frect_t& crop) = 0;
+ virtual Error setLayerTransform(Display display, Layer layer,
+ int32_t transform) = 0;
+ virtual Error setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& visible) = 0;
+ virtual Error setLayerZOrder(Display display, Layer layer,
+ uint32_t z) = 0;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
similarity index 76%
rename from graphics/composer/2.1/default/HwcClient.cpp
rename to graphics/composer/2.1/default/ComposerClient.cpp
index edd161a..49415ee 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -20,8 +20,8 @@
#include <hardware/gralloc1.h>
#include <log/log.h>
+#include "ComposerClient.h"
#include "Hwc.h"
-#include "HwcClient.h"
#include "IComposerCommandBuffer.h"
namespace android {
@@ -230,15 +230,12 @@
}
}
-HwcClient::HwcClient(HwcHal& hal)
- : mHal(hal), mReader(*this), mWriter(kWriterInitialSize)
+ComposerClient::ComposerClient(ComposerBase& hal)
+ : mHal(hal), mWriter(kWriterInitialSize)
{
- if (!sHandleImporter.initialize()) {
- LOG_ALWAYS_FATAL("failed to initialize handle importer");
- }
}
-HwcClient::~HwcClient()
+ComposerClient::~ComposerClient()
{
mHal.enableCallback(false);
mHal.removeClient();
@@ -264,7 +261,15 @@
sHandleImporter.cleanup();
}
-void HwcClient::onHotplug(Display display,
+void ComposerClient::initialize()
+{
+ mReader = createCommandReader();
+ if (!sHandleImporter.initialize()) {
+ LOG_ALWAYS_FATAL("failed to initialize handle importer");
+ }
+}
+
+void ComposerClient::onHotplug(Display display,
IComposerCallback::Connection connected)
{
{
@@ -280,17 +285,18 @@
mCallback->onHotplug(display, connected);
}
-void HwcClient::onRefresh(Display display)
+void ComposerClient::onRefresh(Display display)
{
mCallback->onRefresh(display);
}
-void HwcClient::onVsync(Display display, int64_t timestamp)
+void ComposerClient::onVsync(Display display, int64_t timestamp)
{
mCallback->onVsync(display, timestamp);
}
-Return<void> HwcClient::registerCallback(const sp<IComposerCallback>& callback)
+Return<void> ComposerClient::registerCallback(
+ const sp<IComposerCallback>& callback)
{
// no locking as we require this function to be called only once
mCallback = callback;
@@ -299,13 +305,13 @@
return Void();
}
-Return<uint32_t> HwcClient::getMaxVirtualDisplayCount()
+Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
{
return mHal.getMaxVirtualDisplayCount();
}
-Return<void> HwcClient::createVirtualDisplay(uint32_t width, uint32_t height,
- PixelFormat formatHint, uint32_t outputBufferSlotCount,
+Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
+ uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
createVirtualDisplay_cb hidl_cb)
{
Display display = 0;
@@ -322,7 +328,7 @@
return Void();
}
-Return<Error> HwcClient::destroyVirtualDisplay(Display display)
+Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
{
Error err = mHal.destroyVirtualDisplay(display);
if (err == Error::NONE) {
@@ -334,8 +340,8 @@
return err;
}
-Return<void> HwcClient::createLayer(Display display, uint32_t bufferSlotCount,
- createLayer_cb hidl_cb)
+Return<void> ComposerClient::createLayer(Display display,
+ uint32_t bufferSlotCount, createLayer_cb hidl_cb)
{
Layer layer = 0;
Error err = mHal.createLayer(display, &layer);
@@ -351,7 +357,7 @@
return Void();
}
-Return<Error> HwcClient::destroyLayer(Display display, Layer layer)
+Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
{
Error err = mHal.destroyLayer(display, layer);
if (err == Error::NONE) {
@@ -364,7 +370,7 @@
return err;
}
-Return<void> HwcClient::getActiveConfig(Display display,
+Return<void> ComposerClient::getActiveConfig(Display display,
getActiveConfig_cb hidl_cb)
{
Config config = 0;
@@ -374,7 +380,7 @@
return Void();
}
-Return<Error> HwcClient::getClientTargetSupport(Display display,
+Return<Error> ComposerClient::getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace)
{
@@ -383,7 +389,8 @@
return err;
}
-Return<void> HwcClient::getColorModes(Display display, getColorModes_cb hidl_cb)
+Return<void> ComposerClient::getColorModes(Display display,
+ getColorModes_cb hidl_cb)
{
hidl_vec<ColorMode> modes;
Error err = mHal.getColorModes(display, &modes);
@@ -392,7 +399,7 @@
return Void();
}
-Return<void> HwcClient::getDisplayAttribute(Display display,
+Return<void> ComposerClient::getDisplayAttribute(Display display,
Config config, Attribute attribute,
getDisplayAttribute_cb hidl_cb)
{
@@ -403,7 +410,7 @@
return Void();
}
-Return<void> HwcClient::getDisplayConfigs(Display display,
+Return<void> ComposerClient::getDisplayConfigs(Display display,
getDisplayConfigs_cb hidl_cb)
{
hidl_vec<Config> configs;
@@ -413,7 +420,7 @@
return Void();
}
-Return<void> HwcClient::getDisplayName(Display display,
+Return<void> ComposerClient::getDisplayName(Display display,
getDisplayName_cb hidl_cb)
{
hidl_string name;
@@ -423,7 +430,7 @@
return Void();
}
-Return<void> HwcClient::getDisplayType(Display display,
+Return<void> ComposerClient::getDisplayType(Display display,
getDisplayType_cb hidl_cb)
{
DisplayType type = DisplayType::INVALID;
@@ -433,7 +440,7 @@
return Void();
}
-Return<void> HwcClient::getDozeSupport(Display display,
+Return<void> ComposerClient::getDozeSupport(Display display,
getDozeSupport_cb hidl_cb)
{
bool support = false;
@@ -443,7 +450,7 @@
return Void();
}
-Return<void> HwcClient::getHdrCapabilities(Display display,
+Return<void> ComposerClient::getHdrCapabilities(Display display,
getHdrCapabilities_cb hidl_cb)
{
hidl_vec<Hdr> types;
@@ -457,7 +464,7 @@
return Void();
}
-Return<Error> HwcClient::setClientTargetSlotCount(Display display,
+Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
uint32_t clientTargetSlotCount)
{
std::lock_guard<std::mutex> lock(mDisplayDataMutex);
@@ -472,39 +479,39 @@
return Error::NONE;
}
-Return<Error> HwcClient::setActiveConfig(Display display, Config config)
+Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
{
Error err = mHal.setActiveConfig(display, config);
return err;
}
-Return<Error> HwcClient::setColorMode(Display display, ColorMode mode)
+Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
{
Error err = mHal.setColorMode(display, mode);
return err;
}
-Return<Error> HwcClient::setPowerMode(Display display, PowerMode mode)
+Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
{
Error err = mHal.setPowerMode(display, mode);
return err;
}
-Return<Error> HwcClient::setVsyncEnabled(Display display, Vsync enabled)
+Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
{
Error err = mHal.setVsyncEnabled(display, enabled);
return err;
}
-Return<Error> HwcClient::setInputCommandQueue(
+Return<Error> ComposerClient::setInputCommandQueue(
const MQDescriptorSync<uint32_t>& descriptor)
{
std::lock_guard<std::mutex> lock(mCommandMutex);
- return mReader.setMQDescriptor(descriptor) ?
+ return mReader->setMQDescriptor(descriptor) ?
Error::NONE : Error::NO_RESOURCES;
}
-Return<void> HwcClient::getOutputCommandQueue(
+Return<void> ComposerClient::getOutputCommandQueue(
getOutputCommandQueue_cb hidl_cb)
{
// no locking as we require this function to be called inside
@@ -520,7 +527,7 @@
return Void();
}
-Return<void> HwcClient::executeCommands(uint32_t inLength,
+Return<void> ComposerClient::executeCommands(uint32_t inLength,
const hidl_vec<hidl_handle>& inHandles,
executeCommands_cb hidl_cb)
{
@@ -530,12 +537,12 @@
uint32_t outLength = 0;
hidl_vec<hidl_handle> outHandles;
- if (!mReader.readQueue(inLength, inHandles)) {
+ if (!mReader->readQueue(inLength, inHandles)) {
hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
return Void();
}
- Error err = mReader.parse();
+ Error err = mReader->parse();
if (err == Error::NONE &&
!mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
err = Error::NO_RESOURCES;
@@ -543,18 +550,29 @@
hidl_cb(err, outChanged, outLength, outHandles);
- mReader.reset();
+ mReader->reset();
mWriter.reset();
return Void();
}
-HwcClient::CommandReader::CommandReader(HwcClient& client)
+std::unique_ptr<ComposerClient::CommandReader>
+ComposerClient::createCommandReader()
+{
+ return std::unique_ptr<ComposerClient::CommandReader>(
+ new CommandReader(*this));
+}
+
+ComposerClient::CommandReader::CommandReader(ComposerClient& client)
: mClient(client), mHal(client.mHal), mWriter(client.mWriter)
{
}
-Error HwcClient::CommandReader::parse()
+ComposerClient::CommandReader::~CommandReader()
+{
+}
+
+Error ComposerClient::CommandReader::parse()
{
IComposerClient::Command command;
uint16_t length = 0;
@@ -564,79 +582,7 @@
break;
}
- bool parsed = false;
- switch (command) {
- case IComposerClient::Command::SELECT_DISPLAY:
- parsed = parseSelectDisplay(length);
- break;
- case IComposerClient::Command::SELECT_LAYER:
- parsed = parseSelectLayer(length);
- break;
- case IComposerClient::Command::SET_COLOR_TRANSFORM:
- parsed = parseSetColorTransform(length);
- break;
- case IComposerClient::Command::SET_CLIENT_TARGET:
- parsed = parseSetClientTarget(length);
- break;
- case IComposerClient::Command::SET_OUTPUT_BUFFER:
- parsed = parseSetOutputBuffer(length);
- break;
- case IComposerClient::Command::VALIDATE_DISPLAY:
- parsed = parseValidateDisplay(length);
- break;
- case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
- parsed = parseAcceptDisplayChanges(length);
- break;
- case IComposerClient::Command::PRESENT_DISPLAY:
- parsed = parsePresentDisplay(length);
- break;
- case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
- parsed = parseSetLayerCursorPosition(length);
- break;
- case IComposerClient::Command::SET_LAYER_BUFFER:
- parsed = parseSetLayerBuffer(length);
- break;
- case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
- parsed = parseSetLayerSurfaceDamage(length);
- break;
- case IComposerClient::Command::SET_LAYER_BLEND_MODE:
- parsed = parseSetLayerBlendMode(length);
- break;
- case IComposerClient::Command::SET_LAYER_COLOR:
- parsed = parseSetLayerColor(length);
- break;
- case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
- parsed = parseSetLayerCompositionType(length);
- break;
- case IComposerClient::Command::SET_LAYER_DATASPACE:
- parsed = parseSetLayerDataspace(length);
- break;
- case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
- parsed = parseSetLayerDisplayFrame(length);
- break;
- case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
- parsed = parseSetLayerPlaneAlpha(length);
- break;
- case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
- parsed = parseSetLayerSidebandStream(length);
- break;
- case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
- parsed = parseSetLayerSourceCrop(length);
- break;
- case IComposerClient::Command::SET_LAYER_TRANSFORM:
- parsed = parseSetLayerTransform(length);
- break;
- case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
- parsed = parseSetLayerVisibleRegion(length);
- break;
- case IComposerClient::Command::SET_LAYER_Z_ORDER:
- parsed = parseSetLayerZOrder(length);
- break;
- default:
- parsed = false;
- break;
- }
-
+ bool parsed = parseCommand(command, length);
endCommand();
if (!parsed) {
@@ -649,7 +595,59 @@
return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
}
-bool HwcClient::CommandReader::parseSelectDisplay(uint16_t length)
+bool ComposerClient::CommandReader::parseCommand(
+ IComposerClient::Command command, uint16_t length) {
+ switch (command) {
+ case IComposerClient::Command::SELECT_DISPLAY:
+ return parseSelectDisplay(length);
+ case IComposerClient::Command::SELECT_LAYER:
+ return parseSelectLayer(length);
+ case IComposerClient::Command::SET_COLOR_TRANSFORM:
+ return parseSetColorTransform(length);
+ case IComposerClient::Command::SET_CLIENT_TARGET:
+ return parseSetClientTarget(length);
+ case IComposerClient::Command::SET_OUTPUT_BUFFER:
+ return parseSetOutputBuffer(length);
+ case IComposerClient::Command::VALIDATE_DISPLAY:
+ return parseValidateDisplay(length);
+ case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
+ return parseAcceptDisplayChanges(length);
+ case IComposerClient::Command::PRESENT_DISPLAY:
+ return parsePresentDisplay(length);
+ case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
+ return parseSetLayerCursorPosition(length);
+ case IComposerClient::Command::SET_LAYER_BUFFER:
+ return parseSetLayerBuffer(length);
+ case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
+ return parseSetLayerSurfaceDamage(length);
+ case IComposerClient::Command::SET_LAYER_BLEND_MODE:
+ return parseSetLayerBlendMode(length);
+ case IComposerClient::Command::SET_LAYER_COLOR:
+ return parseSetLayerColor(length);
+ case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
+ return parseSetLayerCompositionType(length);
+ case IComposerClient::Command::SET_LAYER_DATASPACE:
+ return parseSetLayerDataspace(length);
+ case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
+ return parseSetLayerDisplayFrame(length);
+ case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
+ return parseSetLayerPlaneAlpha(length);
+ case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
+ return parseSetLayerSidebandStream(length);
+ case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
+ return parseSetLayerSourceCrop(length);
+ case IComposerClient::Command::SET_LAYER_TRANSFORM:
+ return parseSetLayerTransform(length);
+ case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
+ return parseSetLayerVisibleRegion(length);
+ case IComposerClient::Command::SET_LAYER_Z_ORDER:
+ return parseSetLayerZOrder(length);
+ default:
+ return false;
+ }
+}
+
+bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
{
if (length != CommandWriterBase::kSelectDisplayLength) {
return false;
@@ -661,7 +659,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSelectLayer(uint16_t length)
+bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
{
if (length != CommandWriterBase::kSelectLayerLength) {
return false;
@@ -672,7 +670,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetColorTransform(uint16_t length)
+bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
{
if (length != CommandWriterBase::kSetColorTransformLength) {
return false;
@@ -692,7 +690,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetClientTarget(uint16_t length)
+bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
{
// 4 parameters followed by N rectangles
if ((length - 4) % 4 != 0) {
@@ -720,7 +718,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetOutputBuffer(uint16_t length)
+bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
{
if (length != CommandWriterBase::kSetOutputBufferLength) {
return false;
@@ -744,7 +742,7 @@
return true;
}
-bool HwcClient::CommandReader::parseValidateDisplay(uint16_t length)
+bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
{
if (length != CommandWriterBase::kValidateDisplayLength) {
return false;
@@ -771,7 +769,7 @@
return true;
}
-bool HwcClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
+bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
{
if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
return false;
@@ -785,7 +783,7 @@
return true;
}
-bool HwcClient::CommandReader::parsePresentDisplay(uint16_t length)
+bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
{
if (length != CommandWriterBase::kPresentDisplayLength) {
return false;
@@ -805,7 +803,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
return false;
@@ -820,7 +818,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerBuffer(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerBufferLength) {
return false;
@@ -844,7 +842,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
{
// N rectangles
if (length % 4 != 0) {
@@ -860,7 +858,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerBlendModeLength) {
return false;
@@ -874,7 +872,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerColor(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerColorLength) {
return false;
@@ -888,7 +886,8 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerCompositionType(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerCompositionType(
+ uint16_t length)
{
if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
return false;
@@ -902,7 +901,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerDataspace(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerDataspaceLength) {
return false;
@@ -916,7 +915,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
return false;
@@ -930,7 +929,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
return false;
@@ -944,7 +943,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
return false;
@@ -963,7 +962,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerSourceCropLength) {
return false;
@@ -977,7 +976,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerTransform(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerTransformLength) {
return false;
@@ -991,7 +990,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
{
// N rectangles
if (length % 4 != 0) {
@@ -1007,7 +1006,7 @@
return true;
}
-bool HwcClient::CommandReader::parseSetLayerZOrder(uint16_t length)
+bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
{
if (length != CommandWriterBase::kSetLayerZOrderLength) {
return false;
@@ -1021,7 +1020,7 @@
return true;
}
-hwc_rect_t HwcClient::CommandReader::readRect()
+hwc_rect_t ComposerClient::CommandReader::readRect()
{
return hwc_rect_t{
readSigned(),
@@ -1031,7 +1030,7 @@
};
}
-std::vector<hwc_rect_t> HwcClient::CommandReader::readRegion(size_t count)
+std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
{
std::vector<hwc_rect_t> region;
region.reserve(count);
@@ -1043,7 +1042,7 @@
return region;
}
-hwc_frect_t HwcClient::CommandReader::readFRect()
+hwc_frect_t ComposerClient::CommandReader::readFRect()
{
return hwc_frect_t{
readFloat(),
@@ -1053,8 +1052,8 @@
};
}
-Error HwcClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
- bool useCache, buffer_handle_t& handle)
+Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
+ uint32_t slot, bool useCache, buffer_handle_t& handle)
{
std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
diff --git a/graphics/composer/2.1/default/HwcClient.h b/graphics/composer/2.1/default/ComposerClient.h
similarity index 89%
rename from graphics/composer/2.1/default/HwcClient.h
rename to graphics/composer/2.1/default/ComposerClient.h
index 35a0450..d351cfb 100644
--- a/graphics/composer/2.1/default/HwcClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
-#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
+#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
+#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
#include <mutex>
#include <unordered_map>
@@ -50,10 +50,12 @@
buffer_handle_t mHandle;
};
-class HwcClient : public IComposerClient {
+class ComposerClient : public IComposerClient {
public:
- HwcClient(HwcHal& hal);
- virtual ~HwcClient();
+ ComposerClient(ComposerBase& hal);
+ virtual ~ComposerClient();
+
+ void initialize();
void onHotplug(Display display, IComposerCallback::Connection connected);
void onRefresh(Display display);
@@ -104,7 +106,7 @@
const hidl_vec<hidl_handle>& inHandles,
executeCommands_cb hidl_cb) override;
-private:
+protected:
struct LayerBuffers {
std::vector<BufferClone> Buffers;
BufferClone SidebandStream;
@@ -123,10 +125,15 @@
class CommandReader : public CommandReaderBase {
public:
- CommandReader(HwcClient& client);
+ CommandReader(ComposerClient& client);
+ virtual ~CommandReader();
+
Error parse();
- private:
+ protected:
+ virtual bool parseCommand(IComposerClient::Command command,
+ uint16_t length);
+
bool parseSelectDisplay(uint16_t length);
bool parseSelectLayer(uint16_t length);
bool parseSetColorTransform(uint16_t length);
@@ -169,21 +176,23 @@
0, false, handle);
}
- HwcClient& mClient;
- HwcHal& mHal;
+ ComposerClient& mClient;
+ ComposerBase& mHal;
CommandWriterBase& mWriter;
Display mDisplay;
Layer mLayer;
};
- HwcHal& mHal;
+ virtual std::unique_ptr<CommandReader> createCommandReader();
+
+ ComposerBase& mHal;
// 64KiB minus a small space for metadata such as read/write pointers
static constexpr size_t kWriterInitialSize =
64 * 1024 / sizeof(uint32_t) - 16;
std::mutex mCommandMutex;
- CommandReader mReader;
+ std::unique_ptr<CommandReader> mReader;
CommandWriterBase mWriter;
sp<IComposerCallback> mCallback;
@@ -199,4 +208,4 @@
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_CLIENT_H
+#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 4efb12b..cf82967 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -20,8 +20,8 @@
#include <log/log.h>
+#include "ComposerClient.h"
#include "Hwc.h"
-#include "HwcClient.h"
namespace android {
namespace hardware {
@@ -184,14 +184,15 @@
Return<void> HwcHal::createClient(createClient_cb hidl_cb)
{
Error err = Error::NONE;
- sp<HwcClient> client;
+ sp<ComposerClient> client;
{
std::lock_guard<std::mutex> lock(mClientMutex);
// only one client is allowed
if (mClient == nullptr) {
- client = new HwcClient(*this);
+ client = new ComposerClient(*this);
+ client->initialize();
mClient = client;
} else {
err = Error::NO_RESOURCES;
@@ -203,7 +204,7 @@
return Void();
}
-sp<HwcClient> HwcHal::getClient()
+sp<ComposerClient> HwcHal::getClient()
{
std::lock_guard<std::mutex> lock(mClientMutex);
return (mClient != nullptr) ? mClient.promote() : nullptr;
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index 6420b31..ca08cf0 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -24,6 +24,8 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <hardware/hwcomposer2.h>
+#include "ComposerBase.h"
+
namespace android {
namespace hardware {
namespace graphics {
@@ -38,96 +40,101 @@
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Hdr;
-class HwcClient;
+class ComposerClient;
-class HwcHal : public IComposer {
+class HwcHal : public IComposer, public ComposerBase {
public:
HwcHal(const hw_module_t* module);
virtual ~HwcHal();
+ bool hasCapability(Capability capability) const;
+
// IComposer interface
Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
Return<void> createClient(createClient_cb hidl_cb) override;
- bool hasCapability(Capability capability) const;
-
- void removeClient();
-
- void enableCallback(bool enable);
-
- uint32_t getMaxVirtualDisplayCount();
+ // ComposerBase interface
+ void removeClient() override;
+ void enableCallback(bool enable) override;
+ uint32_t getMaxVirtualDisplayCount() override;
Error createVirtualDisplay(uint32_t width, uint32_t height,
- PixelFormat* format, Display* outDisplay);
- Error destroyVirtualDisplay(Display display);
+ PixelFormat* format, Display* outDisplay) override;
+ Error destroyVirtualDisplay(Display display) override;
- Error createLayer(Display display, Layer* outLayer);
- Error destroyLayer(Display display, Layer layer);
+ Error createLayer(Display display, Layer* outLayer) override;
+ Error destroyLayer(Display display, Layer layer) override;
- Error getActiveConfig(Display display, Config* outConfig);
+ Error getActiveConfig(Display display, Config* outConfig) override;
Error getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
- PixelFormat format, Dataspace dataspace);
- Error getColorModes(Display display, hidl_vec<ColorMode>* outModes);
+ PixelFormat format, Dataspace dataspace) override;
+ Error getColorModes(Display display,
+ hidl_vec<ColorMode>* outModes) override;
Error getDisplayAttribute(Display display, Config config,
- IComposerClient::Attribute attribute, int32_t* outValue);
- Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs);
- Error getDisplayName(Display display, hidl_string* outName);
+ IComposerClient::Attribute attribute, int32_t* outValue) override;
+ Error getDisplayConfigs(Display display,
+ hidl_vec<Config>* outConfigs) override;
+ Error getDisplayName(Display display, hidl_string* outName) override;
Error getDisplayType(Display display,
- IComposerClient::DisplayType* outType);
- Error getDozeSupport(Display display, bool* outSupport);
+ IComposerClient::DisplayType* outType) override;
+ Error getDozeSupport(Display display, bool* outSupport) override;
Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
float* outMaxLuminance, float* outMaxAverageLuminance,
- float* outMinLuminance);
+ float* outMinLuminance) override;
- Error setActiveConfig(Display display, Config config);
- Error setColorMode(Display display, ColorMode mode);
- Error setPowerMode(Display display, IComposerClient::PowerMode mode);
- Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled);
+ Error setActiveConfig(Display display, Config config) override;
+ Error setColorMode(Display display, ColorMode mode) override;
+ Error setPowerMode(Display display,
+ IComposerClient::PowerMode mode) override;
+ Error setVsyncEnabled(Display display,
+ IComposerClient::Vsync enabled) override;
Error setColorTransform(Display display, const float* matrix,
- int32_t hint);
+ int32_t hint) override;
Error setClientTarget(Display display, buffer_handle_t target,
int32_t acquireFence, int32_t dataspace,
- const std::vector<hwc_rect_t>& damage);
+ const std::vector<hwc_rect_t>& damage) override;
Error setOutputBuffer(Display display, buffer_handle_t buffer,
- int32_t releaseFence);
+ int32_t releaseFence) override;
Error validateDisplay(Display display,
std::vector<Layer>* outChangedLayers,
std::vector<IComposerClient::Composition>* outCompositionTypes,
uint32_t* outDisplayRequestMask,
std::vector<Layer>* outRequestedLayers,
- std::vector<uint32_t>* outRequestMasks);
- Error acceptDisplayChanges(Display display);
+ std::vector<uint32_t>* outRequestMasks) override;
+ Error acceptDisplayChanges(Display display) override;
Error presentDisplay(Display display, int32_t* outPresentFence,
std::vector<Layer>* outLayers,
- std::vector<int32_t>* outReleaseFences);
+ std::vector<int32_t>* outReleaseFences) override;
Error setLayerCursorPosition(Display display, Layer layer,
- int32_t x, int32_t y);
+ int32_t x, int32_t y) override;
Error setLayerBuffer(Display display, Layer layer,
- buffer_handle_t buffer, int32_t acquireFence);
+ buffer_handle_t buffer, int32_t acquireFence) override;
Error setLayerSurfaceDamage(Display display, Layer layer,
- const std::vector<hwc_rect_t>& damage);
- Error setLayerBlendMode(Display display, Layer layer, int32_t mode);
+ const std::vector<hwc_rect_t>& damage) override;
+ Error setLayerBlendMode(Display display, Layer layer,
+ int32_t mode) override;
Error setLayerColor(Display display, Layer layer,
- IComposerClient::Color color);
+ IComposerClient::Color color) override;
Error setLayerCompositionType(Display display, Layer layer,
- int32_t type);
+ int32_t type) override;
Error setLayerDataspace(Display display, Layer layer,
- int32_t dataspace);
+ int32_t dataspace) override;
Error setLayerDisplayFrame(Display display, Layer layer,
- const hwc_rect_t& frame);
- Error setLayerPlaneAlpha(Display display, Layer layer, float alpha);
+ const hwc_rect_t& frame) override;
+ Error setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha) override;
Error setLayerSidebandStream(Display display, Layer layer,
- buffer_handle_t stream);
+ buffer_handle_t stream) override;
Error setLayerSourceCrop(Display display, Layer layer,
- const hwc_frect_t& crop);
+ const hwc_frect_t& crop) override;
Error setLayerTransform(Display display, Layer layer,
- int32_t transform);
+ int32_t transform) override;
Error setLayerVisibleRegion(Display display, Layer layer,
- const std::vector<hwc_rect_t>& visible);
- Error setLayerZOrder(Display display, Layer layer, uint32_t z);
+ const std::vector<hwc_rect_t>& visible) override;
+ Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
private:
void initCapabilities();
@@ -136,7 +143,7 @@
void initDispatch(hwc2_function_descriptor_t desc, T* outPfn);
void initDispatch();
- sp<HwcClient> getClient();
+ sp<ComposerClient> getClient();
static void hotplugHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int32_t connected);
@@ -196,7 +203,7 @@
} mDispatch;
std::mutex mClientMutex;
- wp<HwcClient> mClient;
+ wp<ComposerClient> mClient;
};
extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
diff --git a/ir/1.0/vts/functional/ir_hidl_hal_test.cpp b/ir/1.0/vts/functional/ir_hidl_hal_test.cpp
index 57d0b73..08c7974 100644
--- a/ir/1.0/vts/functional/ir_hidl_hal_test.cpp
+++ b/ir/1.0/vts/functional/ir_hidl_hal_test.cpp
@@ -34,7 +34,7 @@
class ConsumerIrHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- ir = IConsumerIr::getService(false);
+ ir = IConsumerIr::getService();
ASSERT_NE(ir, nullptr);
}
diff --git a/ir/1.0/vts/functional/vts/testcases/hal/ir/hidl/target/AndroidTest.xml b/ir/1.0/vts/functional/vts/testcases/hal/ir/hidl/target/AndroidTest.xml
index 3ad7e45..bf3d236 100644
--- a/ir/1.0/vts/functional/vts/testcases/hal/ir/hidl/target/AndroidTest.xml
+++ b/ir/1.0/vts/functional/vts/testcases/hal/ir/hidl/target/AndroidTest.xml
@@ -25,7 +25,7 @@
_64bit::DATA/nativetest64/ir_hidl_hal_test/ir_hidl_hal_test,
"/>
<option name="binary-test-type" value="hal_hidl_gtest" />
- <option name="hwbinder-service" value="android.hardware.ir" />
+ <option name="precondition-hwbinder-service" value="android.hardware.ir" />
<option name="test-timeout" value="1m" />
</test>
</configuration>
diff --git a/keymaster/3.0/IKeymasterDevice.hal b/keymaster/3.0/IKeymasterDevice.hal
index 19669c8..50a41ec 100644
--- a/keymaster/3.0/IKeymasterDevice.hal
+++ b/keymaster/3.0/IKeymasterDevice.hal
@@ -209,6 +209,21 @@
deleteAllKeys() generates(ErrorCode error);
/**
+ * Destroys knowledge of the device's ids. This prevents all device id attestation in the
+ * future. The destruction must be permanent so that not even a factory reset will restore the
+ * device ids.
+ *
+ * Device id attestation may be provided only if this method is fully implemented, allowing the
+ * user to permanently disable device id attestation. If this cannot be guaranteed, the device
+ * must never attest any device ids.
+ *
+ * This is a NOP if device id attestation is not supported.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ destroyAttestationIds() generates(ErrorCode error);
+
+ /**
* Begins a cryptographic operation using the specified key. If all is well, begin() will return
* ErrorCode::OK and create an operation handle which must be passed to subsequent calls to
* update(), finish() or abort().
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
index 1208b8d..563ff84 100644
--- a/keymaster/3.0/default/KeymasterDevice.cpp
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -516,6 +516,24 @@
hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+ for (size_t i = 0; i < attestParams.size(); ++i) {
+ switch (attestParams[i].tag) {
+ case Tag::ATTESTATION_ID_BRAND:
+ case Tag::ATTESTATION_ID_DEVICE:
+ case Tag::ATTESTATION_ID_PRODUCT:
+ case Tag::ATTESTATION_ID_SERIAL:
+ case Tag::ATTESTATION_ID_IMEI:
+ case Tag::ATTESTATION_ID_MEID:
+ // Device id attestation may only be supported if the device is able to permanently
+ // destroy its knowledge of the ids. This device is unable to do this, so it must
+ // never perform any device id attestation.
+ _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
+ return Void();
+ default:
+ break;
+ }
+ }
+
keymaster_cert_chain_t cert_chain{nullptr, 0};
auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
@@ -569,9 +587,16 @@
}
Return<ErrorCode> KeymasterDevice::deleteAllKeys() {
+ if (keymaster_device_->delete_all_keys == nullptr) {
+ return ErrorCode::UNIMPLEMENTED;
+ }
return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
}
+Return<ErrorCode> KeymasterDevice::destroyAttestationIds() {
+ return ErrorCode::UNIMPLEMENTED;
+}
+
Return<void> KeymasterDevice::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) {
diff --git a/keymaster/3.0/default/KeymasterDevice.h b/keymaster/3.0/default/KeymasterDevice.h
index 23767ef..382f45f 100644
--- a/keymaster/3.0/default/KeymasterDevice.h
+++ b/keymaster/3.0/default/KeymasterDevice.h
@@ -71,6 +71,7 @@
upgradeKey_cb _hidl_cb) override;
Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
Return<ErrorCode> deleteAllKeys() override;
+ Return<ErrorCode> destroyAttestationIds() override;
Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
diff --git a/keymaster/3.0/types.hal b/keymaster/3.0/types.hal
index 7123e57..9f29b6a 100644
--- a/keymaster/3.0/types.hal
+++ b/keymaster/3.0/types.hal
@@ -123,6 +123,19 @@
ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
* applications of which one has initiated a
* key attestation */
+ ATTESTATION_ID_BRAND = TagType:BYTES | 710, /* Used to provide the device's brand name to be
+ included in attestation */
+ ATTESTATION_ID_DEVICE = TagType:BYTES | 711, /* Used to provide the device's device name to be
+ included in attestation */
+ ATTESTATION_ID_PRODUCT = TagType:BYTES | 712, /* Used to provide the device's product name to be
+ included in attestation */
+ ATTESTATION_ID_SERIAL = TagType:BYTES | 713, /* Used to provide the device's serial number to be
+ included in attestation */
+ ATTESTATION_ID_IMEI = TagType:BYTES | 714, /* Used to provide the device's IMEI to be included
+ in attestation */
+ ATTESTATION_ID_MEID = TagType:BYTES | 715, /* Used to provide the device's MEID to be included
+ in attestation */
+
/* Tags used only to provide data to or receive data from operations */
ASSOCIATED_DATA = TagType:BYTES | 1000, /* Used to provide associated data for AEAD modes. */
@@ -312,6 +325,7 @@
ATTESTATION_CHALLENGE_MISSING = -63,
KEYMASTER_NOT_CONFIGURED = -64,
ATTESTATION_APPLICATION_ID_MISSING = -65,
+ CANNOT_ATTEST_IDS = -66,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
index 89b7fa2..1f9c4dc 100644
--- a/media/1.0/types.hal
+++ b/media/1.0/types.hal
@@ -40,7 +40,9 @@
uint32_t stride;
PixelFormat format;
uint32_t usage; // TODO: convert to an enum
+ uint32_t generationNumber;
uint64_t layerCount;
+ uint64_t id;
};
/**
@@ -52,25 +54,18 @@
};
/**
- * Ref: frameworks/native/include/binder/IMemory.h
- * Ref: frameworks/native/libs/binder/IMemory.cpp
+ * Ref: frameworks/native/include/android/rect.h
+ * Ref: frameworks/native/include/ui/Rect.h
*/
-
-/**
- * This struct contains attributes for a shared memory buffer that can be put
- * into a union.
- */
-struct SharedMemoryAttributes {
- uint32_t size;
- uint32_t flags; // TODO: convert to an enum
- uint32_t offset;
+struct Rect {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
};
/**
- * A SharedMemory is simply SharedMemoryAttributes plus a native handle.
+ * Ref: frameworks/native/include/ui/Region.h
*/
-struct SharedMemory {
- handle nativeHandle;
- SharedMemoryAttributes attr;
-};
+typedef vec<Rect> Region;
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index 657c23b..f79aabb 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -8,17 +8,21 @@
"types.hal",
"IGraphicBufferSource.hal",
"IOmx.hal",
+ "IOmxBufferProducer.hal",
"IOmxBufferSource.hal",
"IOmxNode.hal",
"IOmxObserver.hal",
+ "IOmxProducerListener.hal",
],
out: [
"android/hardware/media/omx/1.0/types.cpp",
"android/hardware/media/omx/1.0/GraphicBufferSourceAll.cpp",
"android/hardware/media/omx/1.0/OmxAll.cpp",
+ "android/hardware/media/omx/1.0/OmxBufferProducerAll.cpp",
"android/hardware/media/omx/1.0/OmxBufferSourceAll.cpp",
"android/hardware/media/omx/1.0/OmxNodeAll.cpp",
"android/hardware/media/omx/1.0/OmxObserverAll.cpp",
+ "android/hardware/media/omx/1.0/OmxProducerListenerAll.cpp",
],
}
@@ -30,9 +34,11 @@
"types.hal",
"IGraphicBufferSource.hal",
"IOmx.hal",
+ "IOmxBufferProducer.hal",
"IOmxBufferSource.hal",
"IOmxNode.hal",
"IOmxObserver.hal",
+ "IOmxProducerListener.hal",
],
out: [
"android/hardware/media/omx/1.0/types.h",
@@ -46,6 +52,11 @@
"android/hardware/media/omx/1.0/BnHwOmx.h",
"android/hardware/media/omx/1.0/BpHwOmx.h",
"android/hardware/media/omx/1.0/BsOmx.h",
+ "android/hardware/media/omx/1.0/IOmxBufferProducer.h",
+ "android/hardware/media/omx/1.0/IHwOmxBufferProducer.h",
+ "android/hardware/media/omx/1.0/BnOmxBufferProducer.h",
+ "android/hardware/media/omx/1.0/BpOmxBufferProducer.h",
+ "android/hardware/media/omx/1.0/BsOmxBufferProducer.h",
"android/hardware/media/omx/1.0/IOmxBufferSource.h",
"android/hardware/media/omx/1.0/IHwOmxBufferSource.h",
"android/hardware/media/omx/1.0/BnHwOmxBufferSource.h",
@@ -61,6 +72,11 @@
"android/hardware/media/omx/1.0/BnHwOmxObserver.h",
"android/hardware/media/omx/1.0/BpHwOmxObserver.h",
"android/hardware/media/omx/1.0/BsOmxObserver.h",
+ "android/hardware/media/omx/1.0/IOmxProducerListener.h",
+ "android/hardware/media/omx/1.0/IHwOmxProducerListener.h",
+ "android/hardware/media/omx/1.0/BnOmxProducerListener.h",
+ "android/hardware/media/omx/1.0/BpOmxProducerListener.h",
+ "android/hardware/media/omx/1.0/BsOmxProducerListener.h",
],
}
diff --git a/media/omx/1.0/IOmx.hal b/media/omx/1.0/IOmx.hal
index e9f0b76..acb1aae 100644
--- a/media/omx/1.0/IOmx.hal
+++ b/media/omx/1.0/IOmx.hal
@@ -20,6 +20,8 @@
import IOmxNode;
import IOmxObserver;
+import IOmxBufferProducer;
+import IGraphicBufferSource;
/**
* Ref: frameworks/av/include/media/IOMX.h: IOMX
@@ -32,15 +34,15 @@
* Information for an IOmxNode component.
*/
struct ComponentInfo {
- string mName; //< Name of the component.
- vec<string> mRoles; //< Roles of the component.
+ string mName;
+ vec<string> mRoles;
};
/**
* List available components.
*
- * @param[out] status will be the status of the call.
- * @param[out] nodeList will be a list of ComponentInfo.
+ * @param[out] status The status of the call.
+ * @param[out] nodeList The list of ComponentInfo.
*/
listNodes(
) generates (
@@ -51,11 +53,11 @@
/**
* Allocate an IOmxNode instance with the specified component name.
*
- * @param[in] name is the name of the component to create.
- * @param[in] observer is an observer object that will receive messages from
+ * @param[in] name The name of the component to create.
+ * @param[in] observer An observer object that will receive messages from
* the created instance.
- * @param[out] status will be the status of the call.
- * @param[out] omxNode will be the allocated instance of IOmxNode.
+ * @param[out] status The status of the call.
+ * @param[out] omxNode The allocated instance of IOmxNode.
*/
allocateNode(
string name,
@@ -65,5 +67,17 @@
IOmxNode omxNode
);
+ /**
+ * Create an input surface for recording.
+ *
+ * @param[out] producer The associated producer end of the buffer queue.
+ * @param[out] source The associated `IGraphicBufferSource`.
+ */
+ createInputSurface(
+ ) generates (
+ Status status,
+ IOmxBufferProducer producer,
+ IGraphicBufferSource source
+ );
};
diff --git a/media/omx/1.0/IOmxBufferProducer.hal b/media/omx/1.0/IOmxBufferProducer.hal
new file mode 100644
index 0000000..12b5d14
--- /dev/null
+++ b/media/omx/1.0/IOmxBufferProducer.hal
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2016 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 android.hardware.media.omx@1.0;
+
+import android.hardware.graphics.common@1.0::Dataspace;
+import android.hardware.graphics.common@1.0::PixelFormat;
+
+import android.hardware.media@1.0::types;
+import IOmxProducerListener;
+
+/**
+ * Ref: frameworks/native/include/gui/IGraphicBufferProducer.h:
+ * IGraphicBufferProducer
+ * This is a wrapper/wrapped HAL interface for the actual binder interface.
+ */
+interface IOmxBufferProducer {
+
+ /**
+ * Ref: frameworks/native/include/ui/FenceTime.h: FenceTime::Snapshot
+ *
+ * An atomic snapshot of the FenceTime that is flattenable.
+ */
+ struct FenceTimeSnapshot {
+ enum State : int32_t {
+ EMPTY,
+ FENCE,
+ SIGNAL_TIME,
+ };
+ State state;
+ Fence fence;
+ int64_t signalTimeNs;
+ };
+
+ /**
+ * Ref: frameworks/native/include/gui/FrameTimestamp.h: FrameEventsDelta
+ *
+ * A single frame update from the consumer to producer that can be sent
+ * through a HIDL interface. Although this may be sent multiple times for
+ * the same frame as new timestamps are set, Fences only need to be sent
+ * once.
+ */
+ struct FrameEventsDelta {
+ uint32_t index;
+ uint64_t frameNumber;
+ bool addPostCompositeCalled;
+ bool addRetireCalled;
+ bool addReleaseCalled;
+ int64_t postedTimeNs;
+ int64_t requestedPresentTimeNs;
+ int64_t latchTimeNs;
+ int64_t firstRefreshStartTimeNs;
+ int64_t lastRefreshStartTimeNs;
+ int64_t dequeueReadyTime;
+ FenceTimeSnapshot gpuCompositionDoneFence;
+ FenceTimeSnapshot displayPresentFence;
+ FenceTimeSnapshot displayRetireFence;
+ FenceTimeSnapshot releaseFence;
+ };
+
+ /**
+ * Ref: frameworks/native/include/gui/FrameTimestamp.h: FrameEventHistoryDelta
+ *
+ * A collection of updates from consumer to producer that can be sent
+ * through a HIDL interface.
+ */
+ typedef vec<FrameEventsDelta> FrameEventHistoryDelta;
+
+ /**
+ * Modes for disconnection.
+ */
+ enum DisconnectMode : int32_t {
+ /** Disconnect only the specified API. */
+ API,
+ /** Disconnect any API originally connected from the process calling
+ * disconnect. */
+ ALL_LOCAL
+ };
+
+ struct QueueBufferInput {
+ /** A monotonically increasing value in nanoseconds. */
+ int64_t timestamp;
+ /** Whether the timestamp was synthesized at queue time. */
+ int32_t isAutoTimestamp;
+ /** Description of the contents, interpretation depends on format. */
+ Dataspace dataSpace;
+ /** A crop rectangle that's used as a hint to the consumer. */
+ Rect crop;
+ /** A set of flags from NATIVE_WINDOW_SCALING_* in <window.h>. */
+ int32_t scalingMode;
+ /** A set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h>. */
+ uint32_t transform;
+ /** The sticky transform set in Surface (only used by the LEGACY camera
+ * mode). */
+ uint32_t stickyTransform;
+ /** A fence that the consumer must wait on before reading the buffer;
+ * set this to Fence::NO_FENCE if the buffer is ready immediately. */
+ Fence fence;
+ Region surfaceDamage;
+ /** Whether or not the latest frame timestamps should be retrieved from
+ * the consumer. */
+ bool getFrameTimestamps;
+ };
+
+ struct QueueBufferOutput {
+ uint32_t width;
+ uint32_t height;
+ uint32_t transformHint;
+ uint32_t numPendingBuffers;
+ uint64_t nextFrameNumber;
+ FrameEventHistoryDelta frameTimestamps;
+ };
+
+ /**
+ * requestBuffer requests a new buffer for the given index. The server (i.e.
+ * the IOmxBufferProducer implementation) assigns the newly created
+ * buffer to the given slot index, and the client is expected to mirror the
+ * slot->buffer mapping so that it's not necessary to transfer an
+ * AnwBuffer for every dequeue operation.
+ *
+ * The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - one of the two conditions occurred:
+ * * slot was out of range (see above)
+ * * buffer specified by the slot is not dequeued
+ */
+ requestBuffer(
+ int32_t slot
+ ) generates (
+ Status status,
+ AnwBuffer buffer
+ );
+
+ /**
+ * setMaxDequeuedBufferCount sets the maximum number of buffers that can be
+ * dequeued by the producer at one time. If this method succeeds, any new
+ * buffer slots will be both unallocated and owned by the BufferQueue object
+ * (i.e. they are not owned by the producer or consumer). Calling this may
+ * also cause some buffer slots to be emptied. If the caller is caching the
+ * contents of the buffer slots, it should empty that cache after calling
+ * this method.
+ *
+ * This function should not be called with a value of maxDequeuedBuffers
+ * that is less than the number of currently dequeued buffer slots. Doing so
+ * will result in a BAD_VALUE error.
+ *
+ * The buffer count should be at least 1 (inclusive), but at most
+ * (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The
+ * minimum undequeued buffer count can be obtained by calling
+ * query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned.
+ * * BAD_VALUE - one of the below conditions occurred:
+ * * bufferCount was out of range (see above).
+ * * client would have more than the requested number of dequeued
+ * buffers after this call.
+ * * this call would cause the maxBufferCount value to be exceeded.
+ * * failure to adjust the number of available slots.
+ */
+ setMaxDequeuedBufferCount(
+ int32_t maxDequeuedBuffers
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Set the async flag if the producer intends to asynchronously queue
+ * buffers without blocking. Typically this is used for triple-buffering
+ * and/or when the swap interval is set to zero.
+ *
+ * Enabling async mode will internally allocate an additional buffer to
+ * allow for the asynchronous behavior. If it is not enabled queue/dequeue
+ * calls may block.
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned.
+ * * BAD_VALUE - one of the following has occurred:
+ * * this call would cause the maxBufferCount value to be
+ * exceeded
+ * * failure to adjust the number of available slots.
+ */
+ setAsyncMode(
+ bool async
+ ) generates (
+ Status status
+ );
+
+ /**
+ * dequeueBuffer requests a new buffer slot for the client to use. Ownership
+ * of the slot is transfered to the client, meaning that the server will not
+ * use the contents of the buffer associated with that slot.
+ *
+ * The slot index returned may or may not contain a buffer (client-side).
+ * If the slot is empty the client should call requestBuffer to assign a new
+ * buffer to that slot.
+ *
+ * Once the client is done filling this buffer, it is expected to transfer
+ * buffer ownership back to the server with either cancelBuffer on
+ * the dequeued slot or to fill in the contents of its associated buffer
+ * contents and call queueBuffer.
+ *
+ * If dequeueBuffer returns the BUFFER_NEEDS_REALLOCATION flag, the client is
+ * expected to call requestBuffer immediately.
+ *
+ * If dequeueBuffer returns the RELEASE_ALL_BUFFERS flag, the client is
+ * expected to release all of the mirrored slot->buffer mappings.
+ *
+ * The fence parameter will be updated to hold the fence associated with
+ * the buffer. The contents of the buffer must not be overwritten until the
+ * fence signals. If the fence is Fence::NO_FENCE, the buffer may be written
+ * immediately.
+ *
+ * The width and height parameters must be no greater than the minimum of
+ * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
+ * An error due to invalid dimensions might not be reported until
+ * updateTexImage() is called. If width and height are both zero, the
+ * default values specified by setDefaultBufferSize() are used instead.
+ *
+ * If the format is 0, the default format will be used.
+ *
+ * The usage argument specifies gralloc buffer usage flags. The values
+ * are enumerated in <gralloc.h>, e.g. GRALLOC_USAGE_HW_RENDER. These
+ * will be merged with the usage flags specified by
+ * IGraphicBufferConsumer::setConsumerUsageBits.
+ *
+ * This call will block until a buffer is available to be dequeued. If
+ * both the producer and consumer are controlled by the app, then this call
+ * can never block and will return WOULD_BLOCK if no buffer is available.
+ *
+ * A non-negative value with flags set (see above) will be returned upon
+ * success as status.
+ *
+ * Return of a negative means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - both in async mode and buffer count was less than the
+ * max numbers of buffers that can be allocated at once.
+ * * INVALID_OPERATION - cannot attach the buffer because it would cause
+ * too many buffers to be dequeued, either because
+ * the producer already has a single buffer dequeued
+ * and did not set a buffer count, or because a
+ * buffer count was set and this call would cause
+ * it to be exceeded.
+ * * WOULD_BLOCK - no buffer is currently available, and blocking is disabled
+ * since both the producer/consumer are controlled by app
+ * * NO_MEMORY - out of memory, cannot allocate the graphics buffer.
+ * * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
+ * waiting for a buffer to become available.
+ *
+ * All other negative values are an unknown error returned downstream
+ * from the graphics allocator (typically errno).
+ */
+ dequeueBuffer(
+ uint32_t width,
+ uint32_t height,
+ PixelFormat format,
+ uint32_t usage,
+ bool getFrameTimestamps
+ ) generates (
+ Status status,
+ int32_t slot,
+ Fence fence,
+ FrameEventHistoryDelta outTimestamps
+ );
+
+ /**
+ * detachBuffer attempts to remove all ownership of the buffer in the given
+ * slot from the buffer queue. If this call succeeds, the slot will be
+ * freed, and there will be no way to obtain the buffer from this interface.
+ * The freed slot will remain unallocated until either it is selected to
+ * hold a freshly allocated buffer in dequeueBuffer or a buffer is attached
+ * to the slot. The buffer must have already been dequeued, and the caller
+ * must already possesses the sp<AnwBuffer> (i.e., must have called
+ * requestBuffer).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - the given slot number is invalid, either because it is
+ * out of the range [0, NUM_BUFFER_SLOTS), or because the slot
+ * it refers to is not currently dequeued and requested.
+ */
+ detachBuffer(
+ int32_t slot
+ ) generates (
+ Status status
+ );
+
+ /**
+ * detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer,
+ * and detachBuffer in sequence, except for two things:
+ *
+ * 1) It is unnecessary to know the dimensions, format, or usage of the
+ * next buffer.
+ * 2) It will not block, since if it cannot find an appropriate buffer to
+ * return, it will return an error instead.
+ *
+ * Only slots that are free but still contain an AnwBuffer will be
+ * considered, and the oldest of those will be returned. buffer is
+ * equivalent to buffer from the requestBuffer call, and fence is
+ * equivalent to fence from the dequeueBuffer call.
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - either outBuffer or outFence were NULL.
+ * * NO_MEMORY - no slots were found that were both free and contained a
+ * AnwBuffer.
+ */
+ detachNextBuffer(
+ ) generates (
+ Status status,
+ AnwBuffer buffer,
+ Fence fence
+ );
+
+ /**
+ * attachBuffer attempts to transfer ownership of a buffer to the buffer
+ * queue. If this call succeeds, it will be as if this buffer was dequeued
+ * from the returned slot number. As such, this call will fail if attaching
+ * this buffer would cause too many buffers to be simultaneously dequeued.
+ *
+ * If attachBuffer returns the RELEASE_ALL_BUFFERS flag, the caller is
+ * expected to release all of the mirrored slot->buffer mappings.
+ *
+ * A non-negative value with flags set (see above) will be returned upon
+ * success.
+ *
+ * Return of a negative value means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - outSlot or buffer were NULL, invalid combination of
+ * async mode and buffer count override, or the generation
+ * number of the buffer did not match the buffer queue.
+ * * INVALID_OPERATION - cannot attach the buffer because it would cause
+ * too many buffers to be dequeued, either because
+ * the producer already has a single buffer dequeued
+ * and did not set a buffer count, or because a
+ * buffer count was set and this call would cause
+ * it to be exceeded.
+ * * WOULD_BLOCK - no buffer slot is currently available, and blocking is
+ * disabled since both the producer/consumer are
+ * controlled by the app.
+ * * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
+ * waiting for a slot to become available.
+ */
+ attachBuffer(
+ AnwBuffer buffer
+ ) generates (
+ Status status,
+ int32_t slot
+ );
+
+ /**
+ * queueBuffer indicates that the client has finished filling in the
+ * contents of the buffer associated with slot and transfers ownership of
+ * that slot back to the server.
+ *
+ * It is not valid to call queueBuffer on a slot that is not owned
+ * by the client or one for which a buffer associated via requestBuffer
+ * (an attempt to do so will fail with a return value of BAD_VALUE).
+ *
+ * In addition, the input must be described by the client (as documented
+ * below). Any other properties (zero point, etc)
+ * are client-dependent, and should be documented by the client.
+ *
+ * The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+ *
+ * Upon success, the output will be filled with meaningful values
+ * (refer to the documentation below).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - one of the below conditions occurred:
+ * * fence was NULL
+ * * scaling mode was unknown
+ * * both in async mode and buffer count was less than the
+ * max numbers of buffers that can be allocated at once
+ * * slot index was out of range (see above).
+ * * the slot was not in the dequeued state
+ * * the slot was enqueued without requesting a buffer
+ * * crop rect is out of bounds of the buffer dimensions
+ */
+ queueBuffer(
+ int32_t slot,
+ QueueBufferInput input
+ ) generates (
+ Status status,
+ QueueBufferOutput output
+ );
+
+ /**
+ * cancelBuffer indicates that the client does not wish to fill in the
+ * buffer associated with slot and transfers ownership of the slot back to
+ * the server.
+ *
+ * The buffer is not queued for use by the consumer.
+ *
+ * The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+ *
+ * The buffer will not be overwritten until the fence signals. The fence
+ * will usually be the one obtained from dequeueBuffer.
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned or the producer is not
+ * connected.
+ * * BAD_VALUE - one of the below conditions occurred:
+ * * fence was NULL
+ * * slot index was out of range (see above).
+ * * the slot was not in the dequeued state
+ */
+ cancelBuffer(
+ int32_t slot,
+ Fence fence
+ ) generates (
+ Status status
+ );
+
+ /**
+ * query retrieves some information for this surface
+ * 'what' tokens allowed are that of NATIVE_WINDOW_* in <window.h>
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - the buffer queue has been abandoned.
+ * * BAD_VALUE - what was out of range
+ */
+ query(
+ int32_t what
+ ) generates (
+ int32_t result,
+ int32_t value
+ );
+
+ /**
+ * connect attempts to connect a client API to the IOmxBufferProducer.
+ * This must be called before any other IOmxBufferProducer methods are
+ * called except for getAllocator. A consumer must be already connected.
+ *
+ * This method will fail if the connect was previously called on the
+ * IOmxBufferProducer and no corresponding disconnect call was made.
+ *
+ * The listener is an optional binder callback object that can be used if
+ * the producer wants to be notified when the consumer releases a buffer
+ * back to the BufferQueue. It is also used to detect the death of the
+ * producer. If only the latter functionality is desired, there is a
+ * DummyProducerListener class in IProducerListener.h that can be used.
+ *
+ * The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
+ *
+ * The producerControlledByApp should be set to true if the producer is hosted
+ * by an untrusted process (typically app_process-forked processes). If both
+ * the producer and the consumer are app-controlled then all buffer queues
+ * will operate in async mode regardless of the async flag.
+ *
+ * Upon success, the output will be filled with meaningful data
+ * (refer to QueueBufferOutput documentation above).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * NO_INIT - one of the following occurred:
+ * * the buffer queue was abandoned
+ * * no consumer has yet connected
+ * * BAD_VALUE - one of the following has occurred:
+ * * the producer is already connected
+ * * api was out of range (see above).
+ * * output was NULL.
+ * * Failure to adjust the number of available slots. This can
+ * happen because of trying to allocate/deallocate the async
+ * buffer in response to the value of producerControlledByApp.
+ * * DEAD_OBJECT - the token is hosted by an already-dead process
+ *
+ * Additional negative errors may be returned by the internals, they
+ * should be treated as opaque fatal unrecoverable errors.
+ */
+ connect(
+ IOmxProducerListener listener,
+ int32_t api,
+ bool producerControlledByApp
+ ) generates (
+ Status status,
+ QueueBufferOutput output
+ );
+
+ /**
+ * disconnect attempts to disconnect a client API from the
+ * IOmxBufferProducer. Calling this method will cause any subsequent
+ * calls to other IOmxBufferProducer methods to fail except for
+ * getAllocator and connect. Successfully calling connect after this will
+ * allow the other methods to succeed again.
+ *
+ * The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
+ *
+ * Alternatively if mode is AllLocal, then the API value is ignored, and any API
+ * connected from the same PID calling disconnect will be disconnected.
+ *
+ * Disconnecting from an abandoned IOmxBufferProducer is legal and
+ * is considered a no-op.
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * BAD_VALUE - one of the following has occurred:
+ * * the api specified does not match the one that was connected
+ * * api was out of range (see above).
+ * * DEAD_OBJECT - the token is hosted by an already-dead process
+ */
+ disconnect(
+ int32_t api,
+ DisconnectMode mode /* = DisconnectMode::API */
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Attaches a sideband buffer stream to the IOmxBufferProducer.
+ *
+ * A sideband stream is a device-specific mechanism for passing buffers
+ * from the producer to the consumer without using dequeueBuffer/
+ * queueBuffer. If a sideband stream is present, the consumer can choose
+ * whether to acquire buffers from the sideband stream or from the queued
+ * buffers.
+ *
+ * Passing NULL or a different stream handle will detach the previous
+ * handle if any.
+ */
+ setSidebandStream(
+ handle stream
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Allocates buffers based on the given dimensions/format.
+ *
+ * This function will allocate up to the maximum number of buffers
+ * permitted by the current BufferQueue configuration. It will use the
+ * given format, dimensions, and usage bits, which are interpreted in the
+ * same way as for dequeueBuffer, and the async flag must be set the same
+ * way as for dequeueBuffer to ensure that the correct number of buffers are
+ * allocated. This is most useful to avoid an allocation delay during
+ * dequeueBuffer. If there are already the maximum number of buffers
+ * allocated, this function has no effect.
+ */
+ allocateBuffers(
+ uint32_t width,
+ uint32_t height,
+ PixelFormat format,
+ uint32_t usage
+ );
+
+ /**
+ * Sets whether dequeueBuffer is allowed to allocate new buffers.
+ *
+ * Normally dequeueBuffer does not discriminate between free slots which
+ * already have an allocated buffer and those which do not, and will
+ * allocate a new buffer if the slot doesn't have a buffer or if the slot's
+ * buffer doesn't match the requested size, format, or usage. This method
+ * allows the producer to restrict the eligible slots to those which already
+ * have an allocated buffer of the correct size, format, and usage. If no
+ * eligible slot is available, dequeueBuffer will block or return an error
+ * as usual.
+ */
+ allowAllocation(
+ bool allow
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Sets the current generation number of the BufferQueue.
+ *
+ * This generation number will be inserted into any buffers allocated by the
+ * BufferQueue, and any attempts to attach a buffer with a different
+ * generation number will fail. Buffers already in the queue are not
+ * affected and will retain their current generation number. The generation
+ * number defaults to 0.
+ */
+ setGenerationNumber(
+ uint32_t generationNumber
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Returns the name of the connected consumer.
+ */
+ getConsumerName(
+ ) generates (
+ string name
+ );
+
+ /**
+ * Used to enable/disable shared buffer mode.
+ *
+ * When shared buffer mode is enabled the first buffer that is queued or
+ * dequeued will be cached and returned to all subsequent calls to
+ * dequeueBuffer and acquireBuffer. This allows the producer and consumer to
+ * simultaneously access the same buffer.
+ */
+ setSharedBufferMode(
+ bool sharedBufferMode
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Used to enable/disable auto-refresh.
+ *
+ * Auto refresh has no effect outside of shared buffer mode. In shared
+ * buffer mode, when enabled, it indicates to the consumer that it should
+ * attempt to acquire buffers even if it is not aware of any being
+ * available.
+ */
+ setAutoRefresh(
+ bool autoRefresh
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Sets how long dequeueBuffer will wait for a buffer to become available
+ * before returning an error (TIMED_OUT).
+ *
+ * This timeout also affects the attachBuffer call, which will block if
+ * there is not a free slot available into which the attached buffer can be
+ * placed.
+ *
+ * By default, the BufferQueue will wait forever, which is indicated by a
+ * timeout of -1. If set (to a value other than -1), this will disable
+ * non-blocking mode and its corresponding spare buffer (which is used to
+ * ensure a buffer is always available).
+ *
+ * Return of a value other than NO_ERROR means an error has occurred:
+ * * BAD_VALUE - Failure to adjust the number of available slots. This can
+ * happen because of trying to allocate/deallocate the async
+ * buffer.
+ */
+ setDequeueTimeout(
+ int64_t timeoutNs
+ ) generates (
+ Status status
+ );
+
+ /**
+ * Returns the last queued buffer along with a fence which must signal
+ * before the contents of the buffer are read. If there are no buffers in
+ * the queue, buffer.nativeHandle and fence will be null handles.
+ *
+ * transformMatrix is meaningless if buffer.nativeHandle is null.
+ */
+ getLastQueuedBuffer(
+ ) generates (
+ Status status,
+ AnwBuffer buffer,
+ Fence fence,
+ float[16] transformMatrix
+ );
+
+ /**
+ * Gets the frame events that haven't already been retrieved.
+ */
+ getFrameTimestamps(
+ ) generates (
+ FrameEventHistoryDelta timeStamps
+ );
+
+ /**
+ * Returns a unique id for this BufferQueue.
+ */
+ getUniqueId(
+ ) generates (
+ Status status,
+ uint64_t outId
+ );
+
+};
+
+
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
index 5945b44..8729637 100644
--- a/media/omx/1.0/IOmxNode.hal
+++ b/media/omx/1.0/IOmxNode.hal
@@ -35,7 +35,7 @@
/**
* Free the node.
*
- * @param[out] status will be the status of the call.
+ * @param[out] status Status of the call.
*/
freeNode(
) generates (
@@ -45,9 +45,9 @@
/**
* Invoke a command on the node.
*
- * @param[in] cmd indicates the type of the command.
- * @param[in] param is a parameter for the command.
- * @param[out] status will be the status of the call.
+ * @param[in] cmd Type of the command.
+ * @param[in] param Parameter for the command.
+ * @param[out] status Status of the call.
*
* @see OMX_SendCommand() in the OpenMax IL standard.
*/
@@ -61,33 +61,33 @@
/**
* Retrieve a parameter setting from the node.
*
- * @param[in] index indicates the type of the parameter to retrieve.
- * @param[in] inParams holds some information about the retrieval.
- * @param[out] status will be the status of the call.
- * @param[out] outParams will be the current parameter setting.
+ * @param[in] index Type of the parameter to retrieve.
+ * @param[in] inParams Information about the retrieval.
+ * @param[out] status Status of the call.
+ * @param[out] outParams Current parameter setting.
*
* @see OMX_GetParameter() in the OpenMax IL standard.
*/
getParameter(
uint32_t index,
- Bytes inParams // TODO: describe structure better or point at standard
+ Bytes inParams
) generates (
Status status,
- Bytes outParams // TODO: describe structure better or point at standard
+ Bytes outParams
);
/**
* Change a parameter setting of the node.
*
- * @param[in] index indicates the type of the parameter to change.
- * @param[in] params holds the new parameter setting.
- * @param[out] status will be the status of the call.
+ * @param[in] index Type of the parameter to change.
+ * @param[in] params New parameter setting.
+ * @param[out] status Status of the call.
*
* @see OMX_SetParameter() in the OpenMax IL standard.
*/
setParameter(
uint32_t index,
- Bytes params // TODO: describe structure better or point at standard
+ Bytes params
) generates (
Status status
);
@@ -95,33 +95,33 @@
/**
* Retrieve a configuration from the node.
*
- * @param[in] index indicates the type of the configuration to retrieve.
- * @param[in] inConfig holds some information about the retrieval.
- * @param[out] status will be the status of the call.
- * @param[out] outConfig will be the current configuration.
+ * @param[in] index Type of the configuration to retrieve.
+ * @param[in] inConfig Information about the retrieval.
+ * @param[out] status Status of the call.
+ * @param[out] outConfig Current configuration.
*
* @see OMX_GetConfig() in the OpenMax IL standard.
*/
getConfig(
uint32_t index,
- Bytes inConfig // TODO: describe structure better or point at standard
+ Bytes inConfig
) generates (
Status status,
- Bytes outConfig // TODO: describe structure better or point at standard
+ Bytes outConfig
);
/**
* Change a configuration of the node.
*
- * @param[in] index indicates the type of the configuration to change.
- * @param[in] config holds the new configuration.
- * @param[out] status will be the status of the call.
+ * @param[in] index Type of the configuration to change.
+ * @param[in] config New configuration.
+ * @param[out] status Status of the call.
*
* @see OMX_SetConfig() in the OpenMax IL standard.
*/
setConfig(
uint32_t index,
- Bytes config // TODO: describe structure better or point at standard
+ Bytes config
) generates (
Status status
);
@@ -129,8 +129,9 @@
/**
* Set the mode of a port on the node.
*
- * @param[in] portIndex is the index of the port.
- * @param[in] mode is the target mode on the specified port.
+ * @param[in] portIndex Index of the port.
+ * @param[in] mode Target mode on the specified port.
+ * @param[out] status Status of the call.
*/
setPortMode(
uint32_t portIndex,
@@ -143,11 +144,11 @@
* Prepare a port for adaptive playback. This is based on the extension
* "OMX.google.android.index.prepareForAdaptivePlayback".
*
- * @param[in] portIndex is the index of the port.
- * @param[in] enable indicates whether adaptive playback is enabled or not.
- * @param[in] maxFrameWidth specifies the maximum frame width.
- * @param[in] maxFrameHeight specifies the maximum frame height.
- * @param[out] status status will be the status of the call.
+ * @param[in] portIndex Index of the port.
+ * @param[in] enable Whether the adaptive playback is enabled or not.
+ * @param[in] maxFrameWidth Maximum frame width.
+ * @param[in] maxFrameHeight Maximum frame height.
+ * @param[out] status Status of the call.
*/
prepareForAdaptivePlayback(
uint32_t portIndex,
@@ -162,13 +163,12 @@
* Configure a port for a tunneled playback mode. This is based on the
* extension "OMX.google.android.index.configureVideoTunnelMode".
*
- * @param[in] portIndex is the index of the port.
- * @param[in] tunneled indicates whether the tunneled mode is used or not.
- * @param[in] audioHwSync is the HW SYNC ID of the audio HAL output stream
- * to sync the video with.
- * @param[out] status will be the status of the call.
- * @param[out] sidebandHandle will contain the codec-allocated sideband
- * window handle.
+ * @param[in] portIndex Index of the port.
+ * @param[in] tunneled Whether the tunneled mode is used or not.
+ * @param[in] audioHwSync HW SYNC ID of the audio HAL output stream to sync
+ * the video with.
+ * @param[out] status Status of the call.
+ * @param[out] sidebandHandle Codec-allocated sideband window handle.
*/
configureVideoTunnelMode(
uint32_t portIndex,
@@ -183,23 +183,23 @@
* Retrieve the buffer usage on a port. This is based on the extension
* "OMX.google.android.index.getAndroidNativeBufferUsage".
*
- * @param[in] portIndex is the index of the port.
- * @param[out] status will be the status of the call.
- * @param[out] usage will be the usage.
+ * @param[in] portIndex Index of the port.
+ * @param[out] status Status of the call.
+ * @param[out] usage Current graphic buffer usage.
*/
getGraphicBufferUsage(
uint32_t portIndex
) generates (
Status status,
- uint32_t usage // TODO: Ask graphics team to define an enum.
+ uint32_t usage
);
/**
* Set up a listener to events related to the input surface.
*
- * @param[in] bufferSource is the listener object that implements
+ * @param[in] bufferSource Listener object that implements
* IOmxBufferSource.
- * @param[out] status will be the status of the call.
+ * @param[out] status Status of the call.
*
* @see IOmxBufferSource.
*/
@@ -212,13 +212,12 @@
/**
* Allocate an opaque buffer on a port as a native handle.
*
- * @param[in] portIndex is the index of the port.
- * @param[in] size is the desired size of the buffer.
- * @param[out] status will be the status of the call.
- * @param[out] buffer will be the id of the allocated buffer, which will be
- * needed in some other buffer-related function calls.
- * @param[out] nativeHandle will be the native handle of the allocated
- * buffer.
+ * @param[in] portIndex Index of the port.
+ * @param[in] size Desired size of the buffer.
+ * @param[out] status Status of the call.
+ * @param[out] buffer Id of the allocated buffer, which will be needed in
+ * other buffer-related functions.
+ * @param[out] nativeHandle Native handle of the allocated buffer.
*
* @see OMX_AllocateBuffer() in the OpenMax IL standard.
*/
@@ -234,11 +233,11 @@
/**
* Assign a buffer to a port.
*
- * @param[in] portIndex is the index of the port.
- * @param[in] omxBuffer is the buffer to be assigned to the port.
- * @param[out] status will be the status of the call.
- * @param[out] buffer will be the id of the assigned buffer, which will be
- * needed in some other buffer-related function calls.
+ * @param[in] portIndex Index of the port.
+ * @param[in] omxBuffer Buffer to be assigned to the port.
+ * @param[out] status Status of the call.
+ * @param[out] buffer Id of the assigned buffer, which will be needed in
+ * other buffer-related functions.
*
* @see OMX_UseBuffer() in the OpenMax IL standard.
*/
@@ -254,9 +253,9 @@
* Free a buffer previously assigned to a port by allocateSecureBuffer() or
* useBuffer().
*
- * @param[in] portIndex is the index of the port.
- * @param[in] buffer is the id of the buffer to be freed.
- * @param[out] status will be the status of the call.
+ * @param[in] portIndex Index of the port.
+ * @param[in] buffer Id of the buffer to be freed.
+ * @param[out] status Status of the call.
*
* @see OMX_FreeBuffer() in the OpenMax IL standard.
*/
@@ -276,10 +275,10 @@
* the new buffer passed in via \p omxBuffer before OMX_FillThisBuffer() is
* called. Otherwise, \p omxBuffer is not used.
*
- * @param[in] buffer is the id of the buffer to fill.
- * @param[in] omxBuffer points to the new buffer in metadata mode.
- * @param[in] fence is the fence to wait for (if not null).
- * @param[out] status is the status of the call.
+ * @param[in] buffer Id of the buffer to fill.
+ * @param[in] omxBuffer New buffer information (in metadata mode).
+ * @param[in] fence Fence to wait for (if not null).
+ * @param[out] status Status of the call.
*
* @see OMX_FillThisBuffer() in the OpenMax IL standard.
*/
@@ -300,21 +299,19 @@
* the new buffer passed in via \p omxBuffer before OMX_EmptyThisBuffer() is
* called. Otherwise, \p omxBuffer is not used.
*
- * @param[in] buffer is the id of the buffer to fill.
- * @param[in] omxBuffer points to the new buffer in metadata mode.
- * @param[in] flags is put into the header information that is passed to
- * OMX_EmptyBuffer().
- * @param[in] timestampUs is put into the header information that is passed
- * to OMX_EmptyBuffer().
- * @param[in] fence is the fence to wait for (if not null).
- * @param[out] status is the status of the call.
+ * @param[in] buffer Id of the buffer to fill.
+ * @param[in] omxBuffer New buffer information (in metadata mode).
+ * @param[in] flags Flags to be passed to OMX_EmptyBuffer().
+ * @param[in] timestampUs Timestamp OMX_EmptyBuffer().
+ * @param[in] fence Fence to wait for (if not null).
+ * @param[out] status Status of the call.
*
* @see OMX_EmptyThisBuffer() in the OpenMax IL standard.
*/
emptyBuffer(
BufferId buffer,
CodecBuffer omxBuffer,
- uint32_t flags, // TODO: describe structure better or point at standard
+ uint32_t flags,
uint64_t timestampUs,
Fence fence
) generates (
@@ -324,9 +321,9 @@
/**
* Request the node to translate an extension string to an index.
*
- * @param[in] parameterName is the requested extension string.
- * @param[out] status is the status of the call.
- * @param[out] index is the translated index.
+ * @param[in] parameterName Requested extension string.
+ * @param[out] status Status of the call.
+ * @param[out] index Translated index.
*
* @see OMX_GetExtensionIndex() in the OpenMax IL standard.
*/
@@ -343,8 +340,8 @@
* receive the message in batches by the callback
* IOmxObserver::onMessages().
*
- * @param[in] msg is the message to send.
- * @param[out] status is the status of the call.
+ * @param[in] msg Message to send.
+ * @param[out] status Status of the call.
*
* @see IOmxObserver::onMessages().
*/
@@ -354,5 +351,15 @@
Status status
);
+ /**
+ * Set quirks.
+ *
+ * @param[in] quirks Quirks for the component, generally obtained from
+ * MediaCodecList::getQuirksFor().
+ */
+ oneway setQuirks(
+ uint32_t quirks
+ );
+
};
diff --git a/media/omx/1.0/IOmxProducerListener.hal b/media/omx/1.0/IOmxProducerListener.hal
new file mode 100644
index 0000000..7fde93b
--- /dev/null
+++ b/media/omx/1.0/IOmxProducerListener.hal
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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 android.hardware.media.omx@1.0;
+
+/**
+ * Ref: frameworks/native/include/gui/IProducerListener.h: IProducerListener
+ * This is a wrapper/wrapped HAL interface for the actual binder interface.
+ */
+interface IOmxProducerListener {
+ oneway onBufferReleased();
+ needsReleaseNotify() generates (bool result);
+};
+
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
index ccb2ddf..5413344 100644
--- a/media/omx/1.0/types.hal
+++ b/media/omx/1.0/types.hal
@@ -33,10 +33,18 @@
NO_ERROR = 0,
NAME_NOT_FOUND = -2,
+ WOULD_BLOCK = -11,
NO_MEMORY = -12,
+ NO_INIT = -19,
BAD_VALUE = -22,
+ DEAD_OBJECT = -32,
+ INVALID_OPERATION = -38,
+ TIMED_OUT = -110,
ERROR_UNSUPPORTED = -1010,
UNKNOWN_ERROR = -2147483648,
+
+ BUFFER_NEEDS_REALLOCATION = 0x1,
+ RELEASE_ALL_BUFFERS = 0x2,
};
/**
@@ -135,10 +143,11 @@
PRESET,
SHARED_MEM,
ANW_BUFFER,
- NATIVE_HANDLE
+ NATIVE_HANDLE,
};
struct PresetAttributes {
+ uint32_t rangeOffset;
uint32_t rangeLength;
};
@@ -147,7 +156,7 @@
PresetAttributes preset;
// if bufferType == SHARED_MEM
- SharedMemoryAttributes sharedMem;
+ // No additional attributes.
// if bufferType == ANW_BUFFER
AnwBufferAttributes anwBuffer;
@@ -167,14 +176,18 @@
Attributes attr;
/**
- * \p nativeHandle is used only for types SHARED_MEM, ANW_BUFFER and
- * NATIVE_HANDLE.
+ * Used only for types ANW_BUFFER and NATIVE_HANDLE.
*
* (A native handle cannot be put into a union as HIDL currently does not
* support discriminated unions.)
*/
handle nativeHandle;
+ /**
+ * Used only for type SHARED_MEM.
+ */
+ memory sharedMemory;
+
};
/**
diff --git a/memtrack/1.0/default/Memtrack.cpp b/memtrack/1.0/default/Memtrack.cpp
index fa09c25..33a6906 100644
--- a/memtrack/1.0/default/Memtrack.cpp
+++ b/memtrack/1.0/default/Memtrack.cpp
@@ -29,7 +29,7 @@
namespace V1_0 {
namespace implementation {
-Memtrack::Memtrack(memtrack_module_t *module) : mModule(module) {
+Memtrack::Memtrack(const memtrack_module_t *module) : mModule(module) {
if (mModule)
mModule->init(mModule);
}
@@ -73,26 +73,26 @@
}
-IMemtrack* HIDL_FETCH_IMemtrack(const char* name) {
- int ret = 0;
- const hw_module_t* hw_module = NULL;
- memtrack_module_t *memtrack_module = NULL;
+IMemtrack* HIDL_FETCH_IMemtrack(const char* /* name */) {
+ const hw_module_t* hw_module = nullptr;
+ const memtrack_module_t* memtrack_module = nullptr;
+ int err = hw_get_module(MEMTRACK_HARDWARE_MODULE_ID, &hw_module);
+ if (err) {
+ ALOGE ("hw_get_module %s failed: %d", MEMTRACK_HARDWARE_MODULE_ID, err);
+ return nullptr;
+ }
- ret = hw_get_module(name, &hw_module);
- if (ret == 0 && hw_module->methods->open)
- {
- ret = hw_module->methods->open(hw_module, name,
- reinterpret_cast<hw_device_t**>(&memtrack_module));
- if (ret == 0)
- return new Memtrack(memtrack_module);
- else {
+ if (!hw_module->methods || !hw_module->methods->open) {
+ memtrack_module = reinterpret_cast<const memtrack_module_t*>(hw_module);
+ } else {
+ err = hw_module->methods->open(hw_module, MEMTRACK_HARDWARE_MODULE_ID,
+ reinterpret_cast<hw_device_t**>(const_cast<memtrack_module_t**>(&memtrack_module)));
+ if (err) {
ALOGE("Passthrough failed to load legacy HAL.");
+ return nullptr;
}
}
- else {
- ALOGE ("hw_get_module %s failed: %d", name, ret);
- }
- return nullptr;
+ return new Memtrack(memtrack_module);
}
} // namespace implementation
diff --git a/memtrack/1.0/default/Memtrack.h b/memtrack/1.0/default/Memtrack.h
index a3c55e4..0adba76 100644
--- a/memtrack/1.0/default/Memtrack.h
+++ b/memtrack/1.0/default/Memtrack.h
@@ -38,12 +38,12 @@
using ::android::sp;
struct Memtrack : public IMemtrack {
- Memtrack(memtrack_module_t* module);
+ Memtrack(const memtrack_module_t* module);
~Memtrack();
Return<void> getMemory(int32_t pid, MemtrackType type, getMemory_cb _hidl_cb) override;
private:
- memtrack_module_t* mModule;
+ const memtrack_module_t* mModule;
};
extern "C" IMemtrack* HIDL_FETCH_IMemtrack(const char* name);
diff --git a/memtrack/1.0/default/service.cpp b/memtrack/1.0/default/service.cpp
index f705b15..f079743 100644
--- a/memtrack/1.0/default/service.cpp
+++ b/memtrack/1.0/default/service.cpp
@@ -23,5 +23,5 @@
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
- return defaultPassthroughServiceImplementation<IMemtrack>("memtrack");
+ return defaultPassthroughServiceImplementation<IMemtrack>();
}
diff --git a/memtrack/1.0/vts/Android.mk b/memtrack/1.0/vts/Android.mk
index 397f946..fbb5951 100644
--- a/memtrack/1.0/vts/Android.mk
+++ b/memtrack/1.0/vts/Android.mk
@@ -16,6 +16,4 @@
LOCAL_PATH := $(call my-dir)
-include $(call all-subdir-makefiles)
-
-include $(LOCAL_PATH)/functional/vts/testcases/hal/memtrack/hidl/target/Android.mk
+include $(LOCAL_PATH)/functional/vts/testcases/hal/memtrack/hidl/Android.mk
diff --git a/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
index 597b5da..a4b4fa9 100644
--- a/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
+++ b/memtrack/1.0/vts/functional/memtrack_hidl_hal_test.cpp
@@ -37,7 +37,7 @@
class MemtrackHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- memtrack = IMemtrack::getService("memtrack");
+ memtrack = IMemtrack::getService();
ASSERT_NE(memtrack, nullptr);
}
diff --git a/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/Android.mk b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/memtrack/1.0/vts/functional/vts/testcases/hal/memtrack/hidl/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
diff --git a/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp b/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
index a50d88f..a0c5f1a 100644
--- a/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
+++ b/nfc/1.0/vts/functional/nfc_hidl_hal_test.cpp
@@ -40,6 +40,8 @@
/* NCI Commands */
#define CORE_RESET_CMD \
{ 0x20, 0x00, 0x01, 0x00 }
+#define CORE_RESET_CMD_CONFIG_RESET \
+ { 0x20, 0x00, 0x01, 0x01 }
#define CORE_CONN_CREATE_CMD \
{ 0x20, 0x04, 0x02, 0x01, 0x00 }
#define INVALID_COMMAND \
@@ -166,7 +168,7 @@
* WriteCoreReset:
* Sends CORE_RESET_CMD
* Waits for CORE_RESET_RSP
- * Checks the status and the version number
+ * Checks the status, version number and configuration status
*/
TEST_F(NfcHidlTest, WriteCoreReset) {
std::vector<uint8_t> cmd = CORE_RESET_CMD;
@@ -178,6 +180,26 @@
EXPECT_EQ(6ul, last_data_[0].size());
EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
EXPECT_GE(VERSION, last_data_[0][4]);
+ EXPECT_EQ(0ul, last_data_[0][5]);
+}
+
+/*
+ * WriteCoreResetConfigReset:
+ * Sends CORE_RESET_CMD_CONFIG_RESET
+ * Waits for CORE_RESET_RSP
+ * Checks the status, version number and configuration status
+ */
+TEST_F(NfcHidlTest, WriteCoreResetConfigReset) {
+ std::vector<uint8_t> cmd = CORE_RESET_CMD_CONFIG_RESET;
+ NfcData data = cmd;
+ EXPECT_EQ(data.size(), nfc_->write(data));
+ // Wait for CORE_RESET_RSP
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(1ul, last_data_.size());
+ EXPECT_EQ(6ul, last_data_[0].size());
+ EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
+ EXPECT_GE(VERSION, last_data_[0][4]);
+ EXPECT_EQ(1ul, last_data_[0][5]);
}
/*
@@ -273,14 +295,18 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
// Check if the same data was recieved back
EXPECT_EQ(2ul, last_data_.size());
- EXPECT_EQ(data.size(), last_data_[0].size());
+
+ /* It is possible that CORE_CONN_CREDITS_NTF is received before data,
+ * Find the order and do further checks depending on that */
+ uint8_t data_index = last_data_[0].size() == data.size() ? 0 : 1;
+ EXPECT_EQ(data.size(), last_data_[data_index].size());
for (size_t i = 0; i < data.size(); i++) {
- EXPECT_EQ(data[i], last_data_[0][i]);
+ EXPECT_EQ(data[i], last_data_[data_index][i]);
}
- EXPECT_EQ(6ul, last_data_[1].size());
+ EXPECT_EQ(6ul, last_data_[!data_index].size());
// Check if the credit is refilled to 1
- EXPECT_EQ(1, last_data_[1][5]);
+ EXPECT_EQ(1, last_data_[!data_index][5]);
}
}
diff --git a/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/target_profiling/AndroidTest.xml b/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/target_profiling/AndroidTest.xml
index 42c7e22..3b570f9 100644
--- a/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/target_profiling/AndroidTest.xml
+++ b/nfc/1.0/vts/functional/vts/testcases/hal/nfc/hidl/target_profiling/AndroidTest.xml
@@ -25,7 +25,7 @@
_64bit::DATA/nativetest64/nfc_hidl_hal_test/nfc_hidl_hal_test,
"/>
<option name="binary-test-type" value="gtest" />
- <option name="test-timeout" value="20m" />
+ <option name="test-timeout" value="25m" />
<option name="enable-profiling" value="true" />
</test>
</configuration>
diff --git a/power/1.0/default/Power.cpp b/power/1.0/default/Power.cpp
index 6233a14..2ddac0a 100644
--- a/power/1.0/default/Power.cpp
+++ b/power/1.0/default/Power.cpp
@@ -144,24 +144,24 @@
return Void();
}
-IPower* HIDL_FETCH_IPower(const char* name) {
+IPower* HIDL_FETCH_IPower(const char* /* name */) {
int ret = 0;
const hw_module_t* hw_module = NULL;
power_module_t *power_module;
- ret = hw_get_module(name, &hw_module);
+ ret = hw_get_module(POWER_HARDWARE_MODULE_ID, &hw_module);
if (ret == 0 && hw_module->methods->open) {
- ret = hw_module->methods->open(hw_module, name,
+ ret = hw_module->methods->open(hw_module, POWER_HARDWARE_MODULE_ID,
reinterpret_cast<hw_device_t**>(&power_module));
if (ret == 0) {
return new Power(power_module);
}
else {
- ALOGE("Passthrough failed to load legacy HAL.");
+ ALOGE("Passthrough failed to load legacy power HAL.");
return nullptr;
}
}
else {
- ALOGE ("hw_get_module %s failed: %d", name, ret);
+ ALOGE ("hw_get_module %s failed: %d", POWER_HARDWARE_MODULE_ID, ret);
return nullptr;
}
}
diff --git a/power/1.0/default/service.cpp b/power/1.0/default/service.cpp
index f77ff5b..e8618b8 100644
--- a/power/1.0/default/service.cpp
+++ b/power/1.0/default/service.cpp
@@ -23,5 +23,5 @@
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
- return defaultPassthroughServiceImplementation<IPower>("power");
+ return defaultPassthroughServiceImplementation<IPower>();
}
diff --git a/power/1.0/vts/functional/power_hidl_hal_test.cpp b/power/1.0/vts/functional/power_hidl_hal_test.cpp
index 36bdb0a..3f0ef56 100644
--- a/power/1.0/vts/functional/power_hidl_hal_test.cpp
+++ b/power/1.0/vts/functional/power_hidl_hal_test.cpp
@@ -35,7 +35,7 @@
class PowerHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- power = IPower::getService("power");
+ power = IPower::getService();
ASSERT_NE(power, nullptr);
}
diff --git a/radio/1.0/IRadioIndication.hal b/radio/1.0/IRadioIndication.hal
index 79ebf30..fb8666f 100644
--- a/radio/1.0/IRadioIndication.hal
+++ b/radio/1.0/IRadioIndication.hal
@@ -342,10 +342,6 @@
oneway exitEmergencyCallbackMode(RadioIndicationType type);
/*
- * TODO(Consider moving this to separate interface. Client will receive this function with an
- * IRadioResponse interface so that all requests in that IRadioResponse will fail before
- * rilConnected() is received)
- *
* Indicates the ril connects and returns the version
*
* @param type Type of radio indication
@@ -472,4 +468,4 @@
* restart" that explains the cause of the modem restart
*/
oneway modemReset(RadioIndicationType type, string reason);
-};
\ No newline at end of file
+};
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 593dc92..c0a6475 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -117,9 +117,6 @@
ABORTED = 65, // Operation aborted
INVALID_RESPONSE = 66, // Response from vendor had invalid data
- // TODO(May be moved to vendor HAL extension)
- // OEM specific error codes. To be used by OEM when they don't want to reveal
- // specific error codes which would be replaced by Generic failure.
OEM_ERROR_1 = 501,
OEM_ERROR_2 = 502,
OEM_ERROR_3 = 503,
@@ -462,9 +459,6 @@
AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
OEM_DCFAILCAUSE_1 = 0x1001,
- // OEM specific error codes. To be used by OEMs when they don't want to
- // reveal error code which would be replaced by PDP_FAIL_ERROR_UNSPECIFIED
- // TODO(May be moved to vendor HAL extension)
OEM_DCFAILCAUSE_2 = 0x1002,
OEM_DCFAILCAUSE_3 = 0x1003,
OEM_DCFAILCAUSE_4 = 0x1004,
diff --git a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py
index db210d9..3c7fbbb 100644
--- a/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py
+++ b/sensors/1.0/vts/functional/vts/testcases/hal/sensors/hidl/host/SensorsHidlTest.py
@@ -84,7 +84,7 @@
logging.info("PERMISSION_DENIED: %s", sensors_types.PERMISSION_DENIED)
logging.info("INVALID_OPERATION: %s", sensors_types.INVALID_OPERATION)
asserts.assertEqual(sensors_types.OK, 0);
- asserts.assertEqual(sensors_types.BAD_VALUE, 1);
+ asserts.assertEqual(sensors_types.BAD_VALUE, -22);
logging.info("sensor types:")
logging.info("SENSOR_TYPE_ACCELEROMETER: %s", sensors_types.SENSOR_TYPE_ACCELEROMETER)
diff --git a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
index ca8ecdb..9339165 100644
--- a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
+++ b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target/AndroidTest.xml
@@ -25,7 +25,8 @@
_64bit::DATA/nativetest64/soundtrigger_hidl_hal_test/soundtrigger_hidl_hal_test,
"/>
<option name="test-config-path" value="vts/testcases/hal/soundtrigger/hidl/target/HalSoundTriggerHidlTargetBasicTest.config" />
- <option name="binary-test-type" value="gtest" />
+ <option name="binary-test-type" value="hal_hidl_gtest" />
+ <option name="precondition-file-path-prefix" value="*/lib/hw/sound_trigger.primary." />
<option name="test-timeout" value="1m" />
</test>
</configuration>
diff --git a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target_profiling/AndroidTest.xml b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target_profiling/AndroidTest.xml
index e95a406..cd95b5f 100644
--- a/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target_profiling/AndroidTest.xml
+++ b/soundtrigger/2.0/vts/functional/vts/testcases/hal/soundtrigger/hidl/target_profiling/AndroidTest.xml
@@ -19,12 +19,13 @@
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
<test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
- <option name="test-module-name" value="HalSoundTriggerHidlTargetBasicTest" />
+ <option name="test-module-name" value="HalSoundTriggerHidlTargetBasicProfilingTest" />
<option name="binary-test-sources" value="
_32bit::DATA/nativetest/soundtrigger_hidl_hal_test/soundtrigger_hidl_hal_test,
_64bit::DATA/nativetest64/soundtrigger_hidl_hal_test/soundtrigger_hidl_hal_test,
"/>
- <option name="binary-test-type" value="gtest" />
+ <option name="binary-test-type" value="hal_hidl_gtest" />
+ <option name="precondition-file-path-prefix" value="*/lib/hw/sound_trigger.primary." />
<option name="test-timeout" value="1m" />
<option name="enable-profiling" value="true" />
</test>
diff --git a/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp b/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp
index d922169..3c887c8 100644
--- a/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp
+++ b/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp
@@ -50,7 +50,7 @@
class ThermalHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- thermal_ = IThermal::getService(THERMAL_SERVICE_NAME, false);
+ thermal_ = IThermal::getService(THERMAL_SERVICE_NAME);
ASSERT_NE(thermal_, nullptr);
baseSize_ = 0;
names_.clear();
diff --git a/tv/Android.bp b/tv/Android.bp
index 5ad82f4..ac54910 100644
--- a/tv/Android.bp
+++ b/tv/Android.bp
@@ -2,4 +2,5 @@
subdirs = [
"cec/1.0",
"input/1.0",
+ "input/1.0/vts/functional",
]
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk
index ece38d7..14a57a6 100644
--- a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/Android.mk
@@ -16,8 +16,6 @@
LOCAL_PATH := $(call my-dir)
-include $(call all-subdir-makefiles)
-
include $(CLEAR_VARS)
LOCAL_MODULE := TvCecHidlTest
diff --git a/tv/input/1.0/vts/functional/Android.bp b/tv/input/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..979eb99
--- /dev/null
+++ b/tv/input/1.0/vts/functional/Android.bp
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_test {
+ name: "tv_input_hidl_hal_test",
+ gtest: true,
+ srcs: ["tv_input_hidl_hal_test.cpp"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libnativehelper",
+ "libutils",
+ "android.hardware.tv.input@1.0",
+ ],
+ static_libs: ["libgtest"],
+ cflags: [
+// TODO: add --coverage when the segfault issue is fixed.
+// "--coverage",
+ "-O0",
+ "-g",
+ ],
+// ldflags: [
+// "--coverage"
+// ]
+}
+
diff --git a/tv/input/1.0/vts/functional/tv_input_hidl_hal_test.cpp b/tv/input/1.0/vts/functional/tv_input_hidl_hal_test.cpp
new file mode 100644
index 0000000..1279ecd
--- /dev/null
+++ b/tv/input/1.0/vts/functional/tv_input_hidl_hal_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "tv_input_hidl_hal_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/tv/input/1.0/types.h>
+#include <android/hardware/tv/input/1.0/ITvInput.h>
+#include <android/hardware/tv/input/1.0/ITvInputCallback.h>
+
+#include <gtest/gtest.h>
+
+using ::android::hardware::tv::input::V1_0::ITvInput;
+using ::android::hardware::tv::input::V1_0::ITvInputCallback;
+using ::android::hardware::tv::input::V1_0::Result;
+using ::android::hardware::tv::input::V1_0::TvInputType;
+using ::android::hardware::tv::input::V1_0::TvInputDeviceInfo;
+using ::android::hardware::tv::input::V1_0::TvInputEventType;
+using ::android::hardware::tv::input::V1_0::TvInputEvent;
+using ::android::hardware::tv::input::V1_0::TvStreamConfig;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+
+// Simple ITvInputCallback used as part of testing.
+class TvInputCallback : public ITvInputCallback {
+ public:
+ TvInputCallback() {};
+
+ virtual ~TvInputCallback() = default;
+
+ // notify callback function - currently no-op.
+ // TODO: modify it later.
+ Return<void> notify(const TvInputEvent& event) override {
+ return Void();
+ };
+};
+
+
+// The main test class for TV Input HIDL HAL.
+class TvInputHidlTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ // currently test passthrough mode only
+ tv_input = ITvInput::getService();
+ ASSERT_NE(tv_input, nullptr);
+
+ tv_input_callback = new TvInputCallback();
+ ASSERT_NE(tv_input_callback, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<ITvInput> tv_input;
+ sp<ITvInputCallback> tv_input_callback;
+};
+
+
+// A class for test environment setup.
+class TvInputHidlEnvironment : public ::testing::Environment {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+
+ private:
+};
+
+// TODO: remove this test and add meaningful tests.
+TEST_F(TvInputHidlTest, DummyTest) {
+ EXPECT_NE(tv_input, nullptr);
+}
+
+int main(int argc, char **argv) {
+ ::testing::AddGlobalTestEnvironment(new TvInputHidlEnvironment);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
+
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk
index 2703d8c..1757bfe 100644
--- a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/host/Android.mk
@@ -16,8 +16,6 @@
LOCAL_PATH := $(call my-dir)
-include $(call all-subdir-makefiles)
-
include $(CLEAR_VARS)
LOCAL_MODULE := TvInputHidlTest
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/Android.mk b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/Android.mk
new file mode 100644
index 0000000..153da0b
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := HalTvInputHidlTargetTest
+VTS_CONFIG_SRC_DIR := testcases/hal/tv_input/hidl/target
+include test/vts/tools/build/Android.host_config.mk
+
diff --git a/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/AndroidTest.xml b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/AndroidTest.xml
new file mode 100644
index 0000000..4f98940
--- /dev/null
+++ b/tv/input/1.0/vts/functional/vts/testcases/hal/tv_input/hidl/target/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<configuration description="Config for VTS TV Input HIDL HAL's target-side test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+ <option name="push-group" value="HidlHalTest.push" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="HalTvInputHidlTargetTest"/>
+ <option name="binary-test-sources" value="
+ _32bit::DATA/nativetest/tv_input_hidl_hal_test/tv_input_hidl_hal_test,
+ "/>
+ <option name="binary-test-type" value="gtest" />
+ <option name="test-timeout" value="1m" />
+ </test>
+</configuration>
+
diff --git a/update-base-files.sh b/update-base-files.sh
index e2331f5..1eb6b51 100755
--- a/update-base-files.sh
+++ b/update-base-files.sh
@@ -25,6 +25,9 @@
hidl-gen $options \
-o hardware/libhardware/include/hardware/nfc-base.h \
android.hardware.nfc@1.0
+hidl-gen $options \
+ -o hardware/libhardware/include/hardware/gnss-base.h \
+ android.hardware.gnss@1.0
# system/core
hidl-gen $options \
diff --git a/usb/1.0/Android.bp b/usb/1.0/Android.bp
new file mode 100644
index 0000000..8b84a4a
--- /dev/null
+++ b/usb/1.0/Android.bp
@@ -0,0 +1,64 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+ name: "android.hardware.usb@1.0_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.usb@1.0",
+ srcs: [
+ "types.hal",
+ "IUsb.hal",
+ "IUsbCallback.hal",
+ ],
+ out: [
+ "android/hardware/usb/1.0/types.cpp",
+ "android/hardware/usb/1.0/UsbAll.cpp",
+ "android/hardware/usb/1.0/UsbCallbackAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.usb@1.0_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.usb@1.0",
+ srcs: [
+ "types.hal",
+ "IUsb.hal",
+ "IUsbCallback.hal",
+ ],
+ out: [
+ "android/hardware/usb/1.0/types.h",
+ "android/hardware/usb/1.0/IUsb.h",
+ "android/hardware/usb/1.0/IHwUsb.h",
+ "android/hardware/usb/1.0/BnHwUsb.h",
+ "android/hardware/usb/1.0/BpHwUsb.h",
+ "android/hardware/usb/1.0/BsUsb.h",
+ "android/hardware/usb/1.0/IUsbCallback.h",
+ "android/hardware/usb/1.0/IHwUsbCallback.h",
+ "android/hardware/usb/1.0/BnHwUsbCallback.h",
+ "android/hardware/usb/1.0/BpHwUsbCallback.h",
+ "android/hardware/usb/1.0/BsUsbCallback.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.usb@1.0",
+ generated_sources: ["android.hardware.usb@1.0_genc++"],
+ generated_headers: ["android.hardware.usb@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.usb@1.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hidl.base@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hidl.base@1.0",
+ ],
+}
diff --git a/usb/1.0/Android.mk b/usb/1.0/Android.mk
new file mode 100644
index 0000000..0eded5b
--- /dev/null
+++ b/usb/1.0/Android.mk
@@ -0,0 +1,427 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.usb@1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+ android.hidl.base@1.0-java \
+
+
+#
+# Build types.hal (PortDataRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortDataRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortDataRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortMode)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortMode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortMode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortPowerRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortPowerRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortPowerRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortRoleType)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortRoleType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortRoleType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortStatus)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Status)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/Status.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.Status
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsb.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/IUsb.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsb.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::IUsb
+
+$(GEN): $(LOCAL_PATH)/IUsb.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsbCallback.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/IUsbCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::IUsbCallback
+
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.usb@1.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android.hidl.base@1.0-java-static \
+
+
+#
+# Build types.hal (PortDataRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortDataRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortDataRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortMode)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortMode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortMode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortPowerRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortPowerRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortPowerRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortRole)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortRole.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortRole
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortRoleType)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortRoleType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortRoleType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PortStatus)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/PortStatus.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.PortStatus
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Status)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/Status.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::types.Status
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsb.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/IUsb.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsb.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::IUsb
+
+$(GEN): $(LOCAL_PATH)/IUsb.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IUsbCallback.hal
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/IUsbCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IUsbCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0::IUsbCallback
+
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.usb@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/usb/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IUsb.hal
+$(GEN): $(LOCAL_PATH)/IUsbCallback.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava-constants \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.usb@1.0
+
+$(GEN):
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/usb/1.0/IUsb.hal b/usb/1.0/IUsb.hal
new file mode 100644
index 0000000..965326a
--- /dev/null
+++ b/usb/1.0/IUsb.hal
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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 android.hardware.usb@1.0;
+
+import IUsbCallback;
+
+interface IUsb {
+ /*
+ * This function is used to change the port role of a specific port.
+ * For example, when PD_SWAP or PR_SWAP is supported.
+ * This is function is asynchronous. The status of the role switch
+ * will be informed through IUsbCallback object's notifyPortStatusChange
+ * method.
+ *
+ * @param portName name of the port for which the role has to be changed
+ * @param role the new port role.
+ */
+ oneway switchRole(string portName, PortRole role);
+
+ /*
+ * This function is used to register a callback function which is
+ * called by the HAL whenever there is a change in the port state.
+ * i.e. DATA_ROLE, POWER_ROLE or MODE.
+ *
+ * Also the same callback object would be called to inform the caller
+ * of the roleSwitch status.
+ *
+ * @param callback IUsbCallback object used to convey status to the
+ * userspace.
+ */
+ oneway setCallback(IUsbCallback callback);
+
+ /*
+ * This functions is used to request the hal for the current status
+ * status of the Type-C ports. This method is async/oneway. The result of the
+ * query would be sent through the IUsbCallback object's notifyRoleSwitchStatus
+ * to the caller. This api would would let the caller know of the number
+ * of type-c ports that are present and their connection status through the
+ * PortStatus type.
+ */
+ oneway queryPortStatus();
+};
+
diff --git a/usb/1.0/IUsbCallback.hal b/usb/1.0/IUsbCallback.hal
new file mode 100644
index 0000000..b665ba3
--- /dev/null
+++ b/usb/1.0/IUsbCallback.hal
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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 android.hardware.usb@1.0;
+
+/*
+ * Callback object used for all the IUsb async methods which expects a result.
+ * Caller is expected to register the callback object using setCallback method
+ * to receive updates on the PortStatus.
+ */
+interface IUsbCallback {
+ /*
+ * Used to convey the current port status to the caller.
+ * Called either when PortState changes due to the port partner (or)
+ * when caller requested for the PortStatus update through queryPortStatus.
+ *
+ * @param currentPortStatus vector object of current status of all the
+ * typeC ports in the device.
+ * @param retval SUCCESS when query was done successfully.
+ * ERROR otherwise.
+ */
+ oneway notifyPortStatusChange(vec<PortStatus> currentPortStatus, Status retval);
+
+ /*
+ * Used to notify the result of the switchRole call to the caller.
+ *
+ * @param portName name of the port for which the roleswap is requested.
+ * @param newRole the new role requested by the caller.
+ * @param retval SUCCESS if the role switch succeeded. FAILURE otherwise.
+ */
+ oneway notifyRoleSwitchStatus(string portName, PortRole newRole, Status retval);
+};
diff --git a/usb/1.0/default/Android.mk b/usb/1.0/default/Android.mk
new file mode 100644
index 0000000..09d7ce7
--- /dev/null
+++ b/usb/1.0/default/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.usb@1.0-service
+LOCAL_INIT_RC := android.hardware.usb@1.0-service.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+ Usb.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libhidlbase \
+ libhidltransport \
+ liblog \
+ libhwbinder \
+ libutils \
+ libhardware \
+ android.hardware.usb@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/usb/1.0/default/Usb.cpp b/usb/1.0/default/Usb.cpp
new file mode 100644
index 0000000..f46ff66
--- /dev/null
+++ b/usb/1.0/default/Usb.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#include <dirent.h>
+#include <iostream>
+#include <fstream>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cutils/uevent.h>
+#include <sys/epoll.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "Usb.h"
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace V1_0 {
+namespace implementation {
+
+int32_t readFile(std::string filename, std::string& contents) {
+ std::ifstream file(filename);
+
+ if (file.is_open()) {
+ getline(file, contents);
+ file.close();
+ return 0;
+ }
+ return -1;
+}
+
+std::string appendRoleNodeHelper(const std::string portName, PortRoleType type) {
+ std::string node("/sys/class/dual_role_usb/" + portName);
+
+ switch(type) {
+ case PortRoleType::DATA_ROLE:
+ return node + "/data_role";
+ case PortRoleType::POWER_ROLE:
+ return node + "/power_role";
+ default:
+ return node + "/mode";
+ }
+}
+
+std::string convertRoletoString(PortRole role) {
+ if (role.type == PortRoleType::POWER_ROLE) {
+ if (role.role == static_cast<uint32_t> (PortPowerRole::SOURCE))
+ return "source";
+ else if (role.role == static_cast<uint32_t> (PortPowerRole::SINK))
+ return "sink";
+ } else if (role.type == PortRoleType::DATA_ROLE) {
+ if (role.role == static_cast<uint32_t> (PortDataRole::HOST))
+ return "host";
+ if (role.role == static_cast<uint32_t> (PortDataRole::DEVICE))
+ return "device";
+ } else if (role.type == PortRoleType::MODE) {
+ if (role.role == static_cast<uint32_t> (PortMode::UFP))
+ return "ufp";
+ if (role.role == static_cast<uint32_t> (PortMode::DFP))
+ return "dfp";
+ }
+ return "none";
+}
+
+Return<void> Usb::switchRole(const hidl_string& portName,
+ const PortRole& newRole) {
+ std::string filename = appendRoleNodeHelper(std::string(portName.c_str()),
+ newRole.type);
+ std::ofstream file(filename);
+ std::string written;
+
+ ALOGI("filename write: %s role:%d", filename.c_str(), newRole.role);
+
+ if (file.is_open()) {
+ file << convertRoletoString(newRole).c_str();
+ file.close();
+ if (!readFile(filename, written)) {
+ ALOGI("written: %s", written.c_str());
+ if (written == convertRoletoString(newRole)) {
+ ALOGI("Role switch successfull");
+ Return<void> ret =
+ mCallback->notifyRoleSwitchStatus(portName, newRole,
+ Status::SUCCESS);
+ if (!ret.isOk())
+ ALOGE("RoleSwitchStatus error %s",
+ ret.description().c_str());
+ }
+ }
+ }
+
+ Return<void> ret = mCallback->notifyRoleSwitchStatus(portName, newRole, Status::ERROR);
+ if (!ret.isOk())
+ ALOGE("RoleSwitchStatus error %s", ret.description().c_str());
+
+ return Void();
+}
+
+Status getCurrentRoleHelper(std::string portName,
+ PortRoleType type, uint32_t ¤tRole) {
+ std::string filename;
+ std::string roleName;
+
+ if (type == PortRoleType::POWER_ROLE) {
+ filename = "/sys/class/dual_role_usb/" +
+ portName + "/power_role";
+ currentRole = static_cast<uint32_t>(PortPowerRole::NONE);
+ } else if (type == PortRoleType::DATA_ROLE) {
+ filename = "/sys/class/dual_role_usb/" +
+ portName + "/data_role";
+ currentRole = static_cast<uint32_t> (PortDataRole::NONE);
+ } else if (type == PortRoleType::MODE) {
+ filename = "/sys/class/dual_role_usb/" +
+ portName + "/mode";
+ currentRole = static_cast<uint32_t> (PortMode::NONE);
+ }
+
+ if (readFile(filename, roleName)) {
+ ALOGE("getCurrentRole: Failed to open filesystem node");
+ return Status::ERROR;
+ }
+
+ if (roleName == "dfp")
+ currentRole = static_cast<uint32_t> (PortMode::DFP);
+ else if (roleName == "ufp")
+ currentRole = static_cast<uint32_t> (PortMode::UFP);
+ else if (roleName == "source")
+ currentRole = static_cast<uint32_t> (PortPowerRole::SOURCE);
+ else if (roleName == "sink")
+ currentRole = static_cast<uint32_t> (PortPowerRole::SINK);
+ else if (roleName == "host")
+ currentRole = static_cast<uint32_t> (PortDataRole::HOST);
+ else if (roleName == "device")
+ currentRole = static_cast<uint32_t> (PortDataRole::DEVICE);
+ else if (roleName != "none") {
+ /* case for none has already been addressed.
+ * so we check if the role isnt none.
+ */
+ return Status::UNRECOGNIZED_ROLE;
+ }
+ return Status::SUCCESS;
+}
+
+Status getTypeCPortNamesHelper(std::vector<std::string>& names) {
+ DIR *dp;
+
+ dp = opendir("/sys/class/dual_role_usb");
+ if (dp != NULL)
+ {
+rescan:
+ int32_t ports = 0;
+ int32_t current = 0;
+ struct dirent *ep;
+
+ while ((ep = readdir (dp))) {
+ if (ep->d_type == DT_LNK) {
+ ports++;
+ }
+ }
+ names.resize(ports);
+ rewinddir(dp);
+
+ while ((ep = readdir (dp))) {
+ /* Check to see if new ports were added since the first pass. */
+ if (current >= ports) {
+ rewinddir(dp);
+ goto rescan;
+ }
+
+ if (ep->d_type == DT_LNK) {
+ names[current++] = ep->d_name;
+ }
+ }
+
+ closedir (dp);
+ return Status::SUCCESS;
+ }
+
+ ALOGE("Failed to open /sys/class/dual_role_usb");
+ return Status::ERROR;
+}
+
+bool canSwitchRoleHelper(const std::string portName, PortRoleType type) {
+ std::string filename = appendRoleNodeHelper(portName, type);
+ std::ofstream file(filename);
+
+ if (file.is_open()) {
+ file.close();
+ return true;
+ }
+ return false;
+}
+
+Status getPortModeHelper(const std::string portName, PortMode& portMode) {
+ std::string filename = "/sys/class/dual_role_usb/" +
+ std::string(portName.c_str()) + "/supported_modes";
+ std::string modes;
+
+ if (readFile(filename, modes)) {
+ ALOGE("getSupportedRoles: Failed to open filesystem node");
+ return Status::ERROR;
+ }
+
+ if (modes == "ufp dfp")
+ portMode = PortMode::DRP;
+ else if (modes == "ufp")
+ portMode = PortMode::UFP;
+ else if (modes == "dfp")
+ portMode = PortMode::DFP;
+ else
+ return Status::UNRECOGNIZED_ROLE;
+
+ return Status::SUCCESS;
+}
+
+Status getPortStatusHelper (hidl_vec<PortStatus>& currentPortStatus) {
+ std::vector<std::string> names;
+ Status result = getTypeCPortNamesHelper(names);
+
+ if (result == Status::SUCCESS) {
+ currentPortStatus.resize(names.size());
+ for(std::vector<std::string>::size_type i = 0; i != names.size(); i++) {
+ ALOGI("%s", names[i].c_str());
+ currentPortStatus[i].portName = names[i];
+
+ uint32_t currentRole;
+ if (getCurrentRoleHelper(names[i], PortRoleType::POWER_ROLE,
+ currentRole) == Status::SUCCESS) {
+ currentPortStatus[i].currentPowerRole =
+ static_cast<PortPowerRole> (currentRole);
+ } else {
+ ALOGE("Error while retreiving portNames");
+ goto done;
+ }
+
+ if (getCurrentRoleHelper(names[i],
+ PortRoleType::DATA_ROLE, currentRole) == Status::SUCCESS) {
+ currentPortStatus[i].currentDataRole =
+ static_cast<PortDataRole> (currentRole);
+ } else {
+ ALOGE("Error while retreiving current port role");
+ goto done;
+ }
+
+ if (getCurrentRoleHelper(names[i], PortRoleType::MODE,
+ currentRole) == Status::SUCCESS) {
+ currentPortStatus[i].currentMode =
+ static_cast<PortMode> (currentRole);
+ } else {
+ ALOGE("Error while retreiving current data role");
+ goto done;
+ }
+
+ currentPortStatus[i].canChangeMode =
+ canSwitchRoleHelper(names[i], PortRoleType::MODE);
+ currentPortStatus[i].canChangeDataRole =
+ canSwitchRoleHelper(names[i], PortRoleType::DATA_ROLE);
+ currentPortStatus[i].canChangePowerRole =
+ canSwitchRoleHelper(names[i], PortRoleType::POWER_ROLE);
+
+ ALOGI("canChangeMode: %d canChagedata: %d canChangePower:%d",
+ currentPortStatus[i].canChangeMode,
+ currentPortStatus[i].canChangeDataRole,
+ currentPortStatus[i].canChangePowerRole);
+
+ if (getPortModeHelper(names[i], currentPortStatus[i].supportedModes)
+ != Status::SUCCESS) {
+ ALOGE("Error while retrieving port modes");
+ goto done;
+ }
+ }
+ return Status::SUCCESS;
+ }
+done:
+ return Status::ERROR;
+}
+
+Return<void> Usb::queryPortStatus() {
+ hidl_vec<PortStatus> currentPortStatus;
+ Status status;
+
+ status = getPortStatusHelper(currentPortStatus);
+ Return<void> ret = mCallback->notifyPortStatusChange(currentPortStatus,
+ status);
+ if (!ret.isOk())
+ ALOGE("queryPortStatus error %s", ret.description().c_str());
+
+ return Void();
+}
+struct data {
+ int uevent_fd;
+ android::hardware::usb::V1_0::implementation::Usb *usb;
+};
+
+static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
+ char msg[UEVENT_MSG_LEN + 2];
+ char *cp;
+ int n;
+
+ n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
+ if (n <= 0)
+ return;
+ if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
+ return;
+
+ msg[n] = '\0';
+ msg[n + 1] = '\0';
+ cp = msg;
+
+ while (*cp) {
+ if (!strcmp(cp, "SUBSYSTEM=dual_role_usb")) {
+ ALOGE("uevent received %s", cp);
+ if (payload->usb->mCallback != NULL) {
+ hidl_vec<PortStatus> currentPortStatus;
+ Status status = getPortStatusHelper(currentPortStatus);
+ Return<void> ret =
+ payload->usb->mCallback->notifyPortStatusChange(currentPortStatus, status);
+ if (!ret.isOk())
+ ALOGE("error %s", ret.description().c_str());
+ }
+ break;
+ }
+ /* advance to after the next \0 */
+ while (*cp++);
+ }
+}
+
+void* work(void* param) {
+ int epoll_fd, uevent_fd;
+ struct epoll_event ev;
+ int nevents = 0;
+ struct data payload;
+
+ ALOGE("creating thread");
+
+ uevent_fd = uevent_open_socket(64*1024, true);
+
+ if (uevent_fd < 0) {
+ ALOGE("uevent_init: uevent_open_socket failed\n");
+ return NULL;
+ }
+
+ payload.uevent_fd = uevent_fd;
+ payload.usb = (android::hardware::usb::V1_0::implementation::Usb *)param;
+
+ fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
+
+ ev.events = EPOLLIN;
+ ev.data.ptr = (void *)uevent_event;
+
+ epoll_fd = epoll_create(64);
+ if (epoll_fd == -1) {
+ ALOGE("epoll_create failed; errno=%d", errno);
+ goto error;
+ }
+
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
+ ALOGE("epoll_ctl failed; errno=%d", errno);
+ goto error;
+ }
+
+ while (1) {
+ struct epoll_event events[64];
+
+ nevents = epoll_wait(epoll_fd, events, 64, -1);
+ if (nevents == -1) {
+ if (errno == EINTR)
+ continue;
+ ALOGE("usb epoll_wait failed; errno=%d", errno);
+ break;
+ }
+
+ for (int n = 0; n < nevents; ++n) {
+ if (events[n].data.ptr)
+ (*(void (*)(int, struct data *payload))events[n].data.ptr)
+ (events[n].events, &payload);
+ }
+ }
+
+error:
+ close(uevent_fd);
+
+ if (epoll_fd >= 0)
+ close(epoll_fd);
+
+ return NULL;
+}
+
+
+Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {
+
+ if (mCallback != NULL) {
+ ALOGE("Callback already registered");
+ return Void();
+ }
+
+ mCallback = callback;
+ ALOGI("registering callback");
+
+ if (pthread_create(&mPoll, NULL, work, this)) {
+ ALOGE("pthread creation failed %d", errno);
+ mCallback = NULL;
+ return Void();
+ }
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace usb
+} // namespace hardware
+} // namespace android
diff --git a/usb/1.0/default/Usb.h b/usb/1.0/default/Usb.h
new file mode 100644
index 0000000..cf418f4
--- /dev/null
+++ b/usb/1.0/default/Usb.h
@@ -0,0 +1,50 @@
+#ifndef ANDROID_HARDWARE_USB_V1_0_USB_H
+#define ANDROID_HARDWARE_USB_V1_0_USB_H
+
+#include <android/hardware/usb/1.0/IUsb.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <utils/Log.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "android.hardware.usb@1.0-service"
+#define UEVENT_MSG_LEN 2048
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::usb::V1_0::IUsb;
+using ::android::hardware::usb::V1_0::IUsbCallback;
+using ::android::hardware::usb::V1_0::PortRole;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Usb : public IUsb {
+ Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
+ Return<void> setCallback(const sp<IUsbCallback>& callback) override;
+ Return<void> queryPortStatus() override;
+
+ sp<IUsbCallback> mCallback;
+ private:
+ pthread_t mPoll;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace usb
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_USB_V1_0_USB_H
diff --git a/usb/1.0/default/android.hardware.usb@1.0-service.rc b/usb/1.0/default/android.hardware.usb@1.0-service.rc
new file mode 100644
index 0000000..77dfc93
--- /dev/null
+++ b/usb/1.0/default/android.hardware.usb@1.0-service.rc
@@ -0,0 +1,4 @@
+service usb-hal-1-0 /system/bin/hw/android.hardware.usb@1.0-service
+ class hal
+ user system
+ group system
diff --git a/usb/1.0/default/service.cpp b/usb/1.0/default/service.cpp
new file mode 100644
index 0000000..b4db241
--- /dev/null
+++ b/usb/1.0/default/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <hidl/HidlTransportSupport.h>
+#include "Usb.h"
+
+using android::sp;
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::usb::V1_0::IUsb;
+using android::hardware::usb::V1_0::implementation::Usb;
+
+int main() {
+ const char instance[] = "usb_hal";
+
+ android::sp<IUsb> service = new Usb();
+
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+ service->registerAsService(instance);
+
+ ALOGI("USB HAL Ready.");
+ joinRpcThreadpool();
+}
diff --git a/usb/1.0/types.hal b/usb/1.0/types.hal
new file mode 100644
index 0000000..17cd8c7
--- /dev/null
+++ b/usb/1.0/types.hal
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2016 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 android.hardware.usb@1.0;
+
+
+enum Status : uint32_t {
+ SUCCESS = 0,
+
+ /*
+ * error value when the HAL operation fails for reasons not listed here.
+ */
+ ERROR = 1,
+
+ /*
+ * error value returned when input argument is invalid.
+ */
+ INVALID_ARGUMENT = 2,
+
+ /*
+ * error value returned when role string is unrecognized.
+ */
+ UNRECOGNIZED_ROLE = 3,
+};
+
+/*
+ * Denotes the Port role type.
+ * Passed as an argument for functions used to query or change port roles.
+ */
+enum PortRoleType : uint32_t {
+ /*
+ * Denotes the data role of the port.
+ * The port can either be a "host" or a "device" for data.
+ * This maps to the PortDataRole enum.
+ */
+ DATA_ROLE = 0,
+
+ /*
+ * Denotes the power role of the port.
+ * The port can either be a "source" or "sink" for power.
+ * This maps to PortPowerRole enum.
+ */
+ POWER_ROLE = 1,
+
+ /*
+ * USB ports can be a pure DFP port which can only act
+ * as a host. A UFP port which can only act as a device.
+ * Or a dual role ports which can either can as a host or
+ * a device. This property is used to mention them.
+ */
+ MODE = 2,
+};
+
+@export
+enum PortDataRole : uint32_t {
+ /*
+ * Indicates that the port does not have a data role.
+ * In case of DRP, the current data role of the port is only resolved
+ * when the type-c handshake happens.
+ */
+ NONE = 0,
+
+ /*
+ * Indicates that the port is acting as a host for data.
+ */
+ HOST = 1,
+
+ /*
+ * Indicated that the port is acting as a device for data.
+ */
+ DEVICE = 2,
+
+ NUM_DATA_ROLES = 3,
+};
+
+@export
+enum PortPowerRole : uint32_t {
+ /*
+ * Indicates that the port does not have a power role.
+ * In case of DRP, the current power role of the port is only resolved
+ * when the type-c handshake happens.
+ */
+ NONE = 0,
+
+ /*
+ * Indicates that the port is supplying power to the other port.
+ */
+ SOURCE = 1,
+
+ /*
+ * Indicates that the port is sinking power from the other port.
+ */
+ SINK = 2,
+
+ NUM_POWER_ROLES = 3,
+};
+
+@export
+enum PortMode : uint32_t {
+ /*
+ * Indicates that the port does not have a mode.
+ * In case of DRP, the current mode of the port is only resolved
+ * when the type-c handshake happens.
+ */
+ NONE = 0,
+ /*
+ * Indicates that port can only act as device for data and sink for power.
+ */
+ UFP = 1,
+
+ /*
+ * Indicates the port can only act as host for data and source for power.
+ */
+ DFP = 2,
+
+ /*
+ * Indicates can either act as UFP or DFP at a given point of time.
+ */
+ DRP = 3,
+
+ NUM_MODES = 4,
+};
+
+/*
+ * Used as a container to send port role information.
+ */
+struct PortRole {
+ /*
+ * Indicates the type of Port Role.
+ * Maps to the PortRoleType enum.
+ */
+ PortRoleType type;
+
+ /*
+ * when type is HAL_USB_DATA_ROLE pass values from enum PortDataRole.
+ * when type is HAL_USB_POWER_ROLE pass values from enum PortPowerRole.
+ * when type is HAL_USB_MODE pass values from enum PortMode.
+ */
+ uint32_t role;
+};
+
+/*
+ * Used as the container to report data back to the caller.
+ * Represents the current connection status of a single USB port.
+ */
+struct PortStatus {
+ /*
+ * Name of the port.
+ * Used as the port's id by the caller.
+ */
+ string portName;
+
+ /*
+ * Data role of the port.
+ */
+ PortDataRole currentDataRole;
+
+ /*
+ * Power Role of thte port.
+ */
+ PortPowerRole currentPowerRole;
+
+ /*
+ * Mode in which the port is connected.
+ * Can be UFP or DFP.
+ */
+ PortMode currentMode;
+
+ /*
+ * True indicates that the port's mode can
+ * be changed. False otherwise.
+ */
+ bool canChangeMode;
+
+ /*
+ * True indicates that the port's data role
+ * can be changed. False otherwise.
+ * For example, true if Type-C PD PD_SWAP
+ * is supported.
+ */
+ bool canChangeDataRole;
+
+ /*
+ * True indicates that the port's power role
+ * can be changed. False otherwise.
+ * For example, true if Type-C PD PR_SWAP
+ * is supported.
+ */
+ bool canChangePowerRole;
+
+ /*
+ * Identifies the type of the local port.
+ *
+ * UFP - Indicates that port can only act as device for
+ * data and sink for power.
+ * DFP - Indicates the port can only act as host for data
+ * and source for power.
+ * DRP - Indicates can either act as UFP or DFP at a
+ * given point of time.
+ */
+ PortMode supportedModes;
+};
diff --git a/usb/Android.bp b/usb/Android.bp
new file mode 100644
index 0000000..bbb3e4b
--- /dev/null
+++ b/usb/Android.bp
@@ -0,0 +1,4 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+ "1.0",
+]
diff --git a/vehicle/2.0/Android.mk b/vehicle/2.0/Android.mk
index 9544960..1dd0f45 100644
--- a/vehicle/2.0/Android.mk
+++ b/vehicle/2.0/Android.mk
@@ -1081,6 +1081,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (Wheel)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Wheel.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vehicle@2.0::types.Wheel
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build IVehicle.hal
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/IVehicle.java
@@ -2205,6 +2224,25 @@
LOCAL_GENERATED_SOURCES += $(GEN)
#
+# Build types.hal (Wheel)
+#
+GEN := $(intermediates)/android/hardware/vehicle/V2_0/Wheel.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vehicle@2.0::types.Wheel
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build IVehicle.hal
#
GEN := $(intermediates)/android/hardware/vehicle/V2_0/IVehicle.java
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 4a20ea5..dc32252 100644
--- a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -67,7 +67,7 @@
pValue = getValuePool()->obtainFloat(42.42);
}
break;
- case VehicleProperty::VEHICLE_MAPS_DATA_SERVICE:
+ case VehicleProperty::VEHICLE_MAP_SERVICE:
pValue = getValuePool()->obtainComplex();
pValue->value.int32Values = hidl_vec<int32_t> { 10, 20 };
pValue->value.int64Values = hidl_vec<int64_t> { 30, 40 };
@@ -317,10 +317,10 @@
}
TEST_F(VehicleHalManagerTest, get_Complex) {
- invokeGet(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, 0);
+ invokeGet(VehicleProperty::VEHICLE_MAP_SERVICE, 0);
ASSERT_EQ(StatusCode::OK, actualStatusCode);
- ASSERT_EQ(VehicleProperty::VEHICLE_MAPS_DATA_SERVICE, actualValue.prop);
+ ASSERT_EQ(VehicleProperty::VEHICLE_MAP_SERVICE, actualValue.prop);
ASSERT_EQ(3, actualValue.value.bytes.size());
ASSERT_EQ(1, actualValue.value.bytes[0]);
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index b6a5c31..538c022 100644
--- a/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -107,7 +107,7 @@
// Complex data type.
{
- .prop = VehicleProperty::VEHICLE_MAPS_DATA_SERVICE,
+ .prop = VehicleProperty::VEHICLE_MAP_SERVICE,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE
}
diff --git a/vehicle/2.0/types.hal b/vehicle/2.0/types.hal
index a9b706d..9fda4fd 100644
--- a/vehicle/2.0/types.hal
+++ b/vehicle/2.0/types.hal
@@ -226,6 +226,28 @@
| VehicleArea:GLOBAL),
/*
+ * Reports wheel rotational distance in meters since last wheel tick
+ * event
+ *
+ * The value is a vector each element represents distance for individual
+ * wheel in the following order: left front, right front, left rear,
+ * right rear. VehiclePropValue.timestamp must be correctly filled in.
+ *
+ * Vendors must specify wheels that support this sensor in
+ * VehiclePropConfig.configFlags. The format of this field is a bitset of
+ * values from Wheel enum.
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE|VehiclePropertyChangeMode:CONTINUOUS
+ * @access VehiclePropertyAccess:READ
+ * @unit VehicleUnit:METER
+ */
+ WHEEL_TICK = (
+ 0x0306
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:FLOAT_VEC
+ | VehicleArea:GLOBAL),
+
+ /*
* Currently selected gear
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
@@ -964,6 +986,7 @@
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
+ */
AUDIO_PARAMETERS = (
0x907
| VehiclePropertyGroup:SYSTEM
@@ -971,23 +994,44 @@
| VehicleArea:GLOBAL),
/*
- * Index in int32Values for AP_POWER_STATE property.
+ * Property to control power state of application processor
+ *
+ * It is assumed that AP's power state is controller by separate power
+ * controller.
+ *
+ * For configuration information, VehiclePropConfig.configFlags can
+ * have bit flag combining values in VehicleApPowerStateConfigFlag.
+ *
+ * Value format for IVehicle#get / IVehicle#subscribe:
+ * int32Values[0] : vehicle_ap_power_state_type
+ * int32Values[1] : additional parameter relevant for each state,
+ * 0 if not used.
+ * Value format for IVehicle#set:
+ * int32Values[0] : vehicle_ap_power_state_set_type
+ * int32Values[1] : additional parameter relevant for each request. should be 0 if not used.
+ *
+ * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE
+ * @access VEHICLE_PROP_ACCESS_READ_WRITE
*/
- AP_POWER_STATE = (0x00000A00),
+ AP_POWER_STATE = (
+ 0x0A00
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32_VEC
+ | VehicleArea:GLOBAL),
- /*
- * Property to represent brightness of the display. Some cars have single
- * control for the brightness of all displays and this property is to share
- * change in that control.
- *
- * If this is writable, android side can set this value when user changes
- * display brightness from Settings. If this is read only, user may still
- * change display brightness from Settings, but that will not be reflected
- * to other displays.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
+ /*
+ * Property to represent brightness of the display. Some cars have single
+ * control for the brightness of all displays and this property is to share
+ * change in that control.
+ *
+ * If this is writable, android side can set this value when user changes
+ * display brightness from Settings. If this is read only, user may still
+ * change display brightness from Settings, but that will not be reflected
+ * to other displays.
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ_WRITE
+ */
DISPLAY_BRIGHTNESS = (
0x0A01
| VehiclePropertyGroup:SYSTEM
@@ -1713,12 +1757,20 @@
| VehicleArea:GLOBAL),
/*
- * Vehicle Maps Data Service (VMDS) message
+ * Vehicle Maps Service (VMS) message
+ *
+ * This property uses COMPLEX data to communicate vms messages.
+ *
+ * Its contents are to be interpreted as follows:
+ * the indices defined in VmsMessageIntegerValuesIndex are to be used to
+ * read from int32Values;
+ * stringValue is a serialized VMS message as defined in the vms protocol
+ * which is opaque to the framework;
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
*/
- VEHICLE_MAPS_DATA_SERVICE = (
+ VEHICLE_MAP_SERVICE = (
0x0C00
| VehiclePropertyGroup:SYSTEM
| VehiclePropertyType:COMPLEX
@@ -2744,6 +2796,15 @@
NMHC_CATALYST_INCOMPLETE = 0x1 << 17,
};
+enum Wheel : int32_t {
+ UNKNOWN = 0x0,
+
+ LEFT_FRONT = 0x1,
+ RIGHT_FRONT = 0x2,
+ LEFT_REAR = 0x4,
+ RIGHT_REAR = 0x8,
+};
+
enum SecondaryAirStatus : int32_t {
UPSTREAM = 1,
@@ -3043,3 +3104,32 @@
VENDOR_START_INDEX = LAST_SYSTEM_INDEX + 1,
};
+
+/*
+ * This enum lists the types of supported VMS messages.
+ */
+enum VmsMessageType : int32_t {
+ /* A client subscribes to a layer. */
+ SUBSCRIBE = 1,
+
+ /* A client unsubscribes from a layer. */
+ UNSUBSCRIBE = 2,
+
+ /* A client publishes a data packet. */
+ DATA = 3,
+};
+
+/*
+ * This enum provides the canonical mapping for VMS properties that have an
+ * integer value.
+ */
+enum VmsMessageIntegerValuesIndex : int32_t {
+ /* The message type as enumerated by VmsMessageType enum. */
+ VMS_MESSAGE_TYPE = 1,
+
+ /* The layer ID as defined in the vms protocol. */
+ VMS_LAYER_ID = 2,
+
+ /* The version of the VMS layer. */
+ VMS_LAYER_VERSION = 3,
+};
diff --git a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
index cd52abf..7854c7b 100644
--- a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
+++ b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
@@ -108,19 +108,89 @@
break
return isLiveSupported, isFreezeSupported
+ def readVhalProperty(self, propertyId, areaId=0):
+ """Reads a specified property from Vehicle HAL.
+
+ Args:
+ propertyId: the numeric identifier of the property to be read.
+ areaId: the numeric identifier of the vehicle area to retrieve the
+ property for. 0, or omitted, for global.
+
+ Returns:
+ the value of the property as read from Vehicle HAL, or None
+ if it could not read successfully.
+ """
+ vp_dict = {
+ 'prop' : propertyId,
+ 'timestamp' : 0,
+ 'areaId' : areaId,
+ 'value' : {
+ 'int32Values' : [],
+ 'floatValues' : [],
+ 'int64Values' : [],
+ 'bytes' : [],
+ 'stringValue' : ""
+ }
+ }
+ vp = self.vtypes.Py2Pb("VehiclePropValue", vp_dict)
+ status, value = self.vehicle.get(vp)
+ if self.vtypes.OK == status:
+ return value
+ else:
+ logging.warning("attempt to read property %s returned error %d",
+ propertyId, status)
+
def testObd2SensorProperties(self):
"""Test reading the live and freeze OBD2 frame properties.
OBD2 (On-Board Diagnostics 2) is the industry standard protocol
for retrieving diagnostic sensor information from vehicles.
"""
+ class CheckRead(object):
+ """This class wraps the logic of an actual property read.
+
+ Attributes:
+ testobject: the test case this object is used on behalf of.
+ propertyId: the identifier of the Vehiche HAL property to read.
+ name: the engineer-readable name of this test operation.
+ """
+
+ def __init__(self, testobject, propertyId, name):
+ self.testobject = testobject
+ self.propertyId = propertyId
+ self.name = name
+
+ def onReadSuccess(self, propValue):
+ """Override this to perform any post-read validation.
+
+ Args:
+ propValue: the property value obtained from Vehicle HAL.
+ """
+ pass
+
+ def __call__(self):
+ """Reads the specified property and validates the result."""
+ propValue = self.testobject.readVhalProperty(self.propertyId)
+ asserts.assertNotEqual(propValue, None,
+ msg="reading %s should not return None" %
+ self.name)
+ logging.info("%s = %s", self.name, propValue)
+ self.onReadSuccess(propValue)
+ logging.info("%s pass" % self.name)
+
def checkLiveFrameRead():
"""Validates reading the OBD2_LIVE_FRAME (if available)."""
- logging.info("checkLiveFrameRead no-op pass")
+ checker = CheckRead(self,
+ self.vtypes.OBD2_LIVE_FRAME,
+ "OBD2_LIVE_FRAME")
+ checker()
def checkFreezeFrameRead():
"""Validates reading the OBD2_FREEZE_FRAME (if available)."""
- logging.info("checkLiveFrameRead no-op pass")
+ checker = CheckRead(self,
+ self.vtypes.OBD2_FREEZE_FRAME,
+ "OBD2_FREEZE_FRAME")
+ checker()
isLiveSupported, isFreezeSupported = self.getSupportInfo()
logging.info("isLiveSupported = %s, isFreezeSupported = %s",
@@ -130,5 +200,39 @@
if isFreezeSupported:
checkFreezeFrameRead()
+ def createVehiclePropValue(self, propId):
+ value = {
+ "int32Values" : [],
+ "floatValues" : [],
+ "int64Values" : [],
+ "bytes": [],
+ "stringValue": ""
+ }
+ propValue = {
+ "prop": propId,
+ "timestamp": 0,
+ "areaId": 0,
+ "value": value
+ }
+ return self.vtypes.Py2Pb("VehiclePropValue", propValue)
+
+ def testDrivingStatus(self):
+ """Checks that DRIVING_STATUS property returns correct result."""
+ request = self.createVehiclePropValue(self.vtypes.DRIVING_STATUS)
+ logging.info("Driving status request: %s", request)
+ response = self.vehicle.get(request)
+ logging.info("Driving status response: %s", response)
+ status = response[0]
+ asserts.assertEqual(self.vtypes.OK, status)
+ propValue = response[1]
+ assertEqual(1, len(propValue.value.int32Values))
+ drivingStatus = propValue.value.int32Values[0]
+
+ allStatuses = (self.vtypes.UNRESTRICTED | self.vtypes.NO_VIDEO
+ | self.vtypes.NO_KEYBOARD_INPUT | self.vtypes.NO_VOICE_INPUT
+ | self.vtypes.NO_CONFIG | self.vtypes.LIMIT_MESSAGE_LEN)
+
+ assertEqual(allStatuses, allStatuses | drivingStatus)
+
if __name__ == "__main__":
test_runner.main()
diff --git a/vehicle/2.0/vts/types.vts b/vehicle/2.0/vts/types.vts
index fa7d892..067a7d6 100644
--- a/vehicle/2.0/vts/types.vts
+++ b/vehicle/2.0/vts/types.vts
@@ -494,7 +494,7 @@
scalar_value: {
int32_t: 287312836
}
- enumerator: "VEHICLE_MAPS_DATA_SERVICE"
+ enumerator: "VEHICLE_MAP_SERVICE"
scalar_value: {
int32_t: 299895808
}
diff --git a/vibrator/1.0/default/service.cpp b/vibrator/1.0/default/service.cpp
index 064e1e2..7cc0744 100644
--- a/vibrator/1.0/default/service.cpp
+++ b/vibrator/1.0/default/service.cpp
@@ -22,5 +22,5 @@
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
- return defaultPassthroughServiceImplementation<IVibrator>("vibrator");
+ return defaultPassthroughServiceImplementation<IVibrator>();
}
diff --git a/vibrator/1.0/vts/functional/vibrator_hidl_hal_test.cpp b/vibrator/1.0/vts/functional/vibrator_hidl_hal_test.cpp
index 782a763..435b002 100644
--- a/vibrator/1.0/vts/functional/vibrator_hidl_hal_test.cpp
+++ b/vibrator/1.0/vts/functional/vibrator_hidl_hal_test.cpp
@@ -32,7 +32,7 @@
class VibratorHidlTest : public ::testing::Test {
public:
virtual void SetUp() override {
- vibrator = IVibrator::getService(false);
+ vibrator = IVibrator::getService();
ASSERT_NE(vibrator, nullptr);
}
diff --git a/vr/1.0/vts/functional/vr_hidl_hal_test.cpp b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
index 85ecbdc..7e85337 100644
--- a/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
+++ b/vr/1.0/vts/functional/vr_hidl_hal_test.cpp
@@ -32,8 +32,7 @@
class VrHidlTest : public ::testing::Test {
public:
void SetUp() override {
- // currently test passthrough mode only
- vr = IVr::getService(VR_SERVICE_NAME, true);
+ vr = IVr::getService(VR_SERVICE_NAME);
ASSERT_NE(vr, nullptr);
ASSERT_TRUE(!vr->isRemote());
}
diff --git a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml
index aa5a48f..8c7a9b7 100644
--- a/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml
+++ b/vr/1.0/vts/functional/vts/testcases/hal/vr/hidl/target/AndroidTest.xml
@@ -25,9 +25,11 @@
_64bit::DATA/nativetest64/vr_hidl_hal_test/vr_hidl_hal_test,
"/>
<option name="binary-test-type" value="hal_hidl_gtest" />
- <option name="hwbinder-service" value="android.hardware.vr" />
+ <!-- Uncomment this and comment 'precondition-feature' to run this test
+ only on devices using binderized VR HALs.
+ <option name="precondition-hwbinder-service" value="android.hardware.vr" /> -->
+ <option name="precondition-feature" value="android.hardware.vr.high_performance" />
<option name="test-timeout" value="1m" />
<option name="test-config-path" value="vts/testcases/hal/vr/hidl/target/VrHidlTargetTest.config" />
</test>
</configuration>
-
diff --git a/wifi/supplicant/1.0/ISupplicantIface.hal b/wifi/supplicant/1.0/ISupplicantIface.hal
index c0058a0..8bb8c97 100644
--- a/wifi/supplicant/1.0/ISupplicantIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantIface.hal
@@ -138,6 +138,19 @@
setWpsDeviceName(string name) generates (SupplicantStatus status);
/**
+ * Set the device type for WPS operations.
+ *
+ * @parm type Type of device. Refer to section B.1 of Wifi P2P
+ * Technical specification v1.2.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ setWpsDeviceType(uint8_t[8] type) generates (SupplicantStatus status);
+
+ /**
* Set the manufacturer for WPS operations.
* The manufacturer of the device (up to |WPS_MANUFACTURER_MAX_LEN| ASCII
* characters).
diff --git a/wifi/supplicant/1.0/ISupplicantStaIface.hal b/wifi/supplicant/1.0/ISupplicantStaIface.hal
index c9d9ee6..68eb179 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIface.hal
@@ -67,6 +67,10 @@
SENSE = 2
};
+ enum ExtRadioWorkDefaults : uint32_t {
+ TIMEOUT_IN_SECS = 10
+ };
+
/**
* Register for callbacks from this interface.
*
@@ -405,4 +409,55 @@
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
setExternalSim(bool useExternalSim) generates (SupplicantStatus status);
+
+ /**
+ * External programs can request supplicant to not start offchannel
+ * operations during other tasks that may need exclusive control of the
+ * radio.
+ *
+ * This method can be used to reserve a slot for radio access. If freq is
+ * specified, other radio work items on the same channel can be completed in
+ * parallel. Otherwise, all other radio work items are blocked during
+ * execution. Timeout must be set to |ExtRadioWorkDefaults.TIMEOUT_IN_SECS|
+ * seconds by default to avoid blocking supplicant operations on the iface
+ * for excessive time. If a longer (or shorter) safety timeout is needed,
+ * that may be specified with the optional timeout parameter. This command
+ * returns an identifier for the radio work item.
+ *
+ * Once the radio work item has been started,
+ * |ISupplicant.onExtRadioWorkStart| callback is indicated that the external
+ * processing can start.
+ *
+ * @param name Name for the radio work being added.
+ * @param freqInMhz Frequency to specify. Set to 0 for all channels.
+ * @param timeoutInSec Timeout tospecify. Set to 0 for default timeout.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * @return id Identifier for this radio work.
+ */
+ addExtRadioWork(string name, uint32_t freqInMhz, uint32_t timeoutInSec)
+ generates (SupplicantStatus status, uint32_t id);
+
+ /**
+ * Indicates to supplicant that the external radio work has completed.
+ * This allows other radio works to be performed. If this method is not
+ * invoked (e.g., due to the external program terminating), supplicant
+ * must time out the radio work item on the iface and send
+ * |ISupplicantCallback.onExtRadioWorkTimeout| event to indicate
+ * that this has happened.
+ *
+ * This method may also be used to cancel items that have been scheduled
+ * via |addExtRadioWork|, but have not yet been started (notified via
+ * |ISupplicantCallback.onExtRadioWorkStart|).
+ *
+ * @return id Identifier generated for the radio work addition
+ * (using |addExtRadioWork|).
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ removeExtRadioWork(uint32_t id) generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
index 4b201d4..c3ec060 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
@@ -326,4 +326,18 @@
* Used to indicate the overlap of a WPS PBC connection attempt.
*/
oneway onWpsEventPbcOverlap();
+
+ /**
+ * Used to indicate that the external radio work can start now.
+ *
+ * @return id Identifier generated for the radio work request.
+ */
+ oneway onExtRadioWorkStart(uint32_t id);
+
+ /**
+ * Used to indicate that the external radio work request has timed out.
+ *
+ * @return id Identifier generated for the radio work request.
+ */
+ oneway onExtRadioWorkTimeout(uint32_t id);
};
diff --git a/wifi/supplicant/1.0/ISupplicantStaNetwork.hal b/wifi/supplicant/1.0/ISupplicantStaNetwork.hal
index b347c1d..deaad5d 100644
--- a/wifi/supplicant/1.0/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaNetwork.hal
@@ -508,8 +508,30 @@
*/
setEapDomainSuffixMatch(string match)
generates (SupplicantStatus status);
+
/**
- * Get ID string set for this network.
+ * This field can be used to enable proactive key caching which is also
+ * known as opportunistic PMKSA caching for WPA2. This is disabled (0)
+ * by default unless default value is changed with the global okc=1
+ * parameter.
+ *
+ * Proactive key caching is used to make supplicant assume that the APs
+ * are using the same PMK and generate PMKSA cache entries without
+ * doing RSN pre-authentication. This requires support from the AP side
+ * and is normally used with wireless switches that co-locate the
+ * authenticator.
+ *
+ * @param enable true to set, false otherwise.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ setProactiveKeyCaching(bool enable) generates (SupplicantStatus status);
+
+ /**
+ * Set ID string for this network.
* Network identifier string for external scripts.
*
* @return idStr ID string value to set.
@@ -523,6 +545,20 @@
setIdStr(string idStr) generates (SupplicantStatus status);
/**
+ * Set PPS MO ID for this network.
+ * (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
+ *
+ * @return id ID value to set.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ setUpdateIdentifier(uint32_t id) generates (SupplicantStatus status);
+
+ /**
* Getters for the various network params.
*/
/**
@@ -912,11 +948,23 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
- sendNetworkEapSimGsmAuthResponse(NetworkResponseEapSimGsmAuthParams params)
+ sendNetworkEapSimGsmAuthResponse(vec<NetworkResponseEapSimGsmAuthParams> params)
generates (SupplicantStatus status);
/**
* Used to send a response to the
+ * |ISupplicantNetworkCallback.onNetworkEapSimGsmAuthRequest| request.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ sendNetworkEapSimGsmAuthFailure() generates (SupplicantStatus status);
+
+ /**
+ * Used to send a response to the
* |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
*
* @param params Params to be used for EAP UMTS authentication.
@@ -931,6 +979,32 @@
/**
* Used to send a response to the
+ * |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
+ *
+ * @param auts Params to be used for EAP UMTS authentication.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ sendNetworkEapSimUmtsAutsResponse(uint8_t[14] auts)
+ generates (SupplicantStatus status);
+
+ /**
+ * Used to send a response to the
+ * |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ sendNetworkEapSimUmtsAuthFailure() generates (SupplicantStatus status);
+
+ /**
+ * Used to send a response to the
* |ISupplicantNetworkCallback.onNetworkEapIdentityRequest| request.
*
* @param identity Identity to be used for the network.