Merge "Remove vibrator@1.4"
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index d3d7387..a4e95ed 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -64,7 +64,7 @@
// The error passed to the last onError() callback.
FaceError error;
- // The userId passed to the last onRemoved() callback.
+ // The userId passed to the last callback.
int32_t userId;
};
@@ -74,24 +74,32 @@
class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase<FaceCallbackArgs>,
public IBiometricsFaceClientCallback {
public:
- Return<void> onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override {
- NotifyFromCallback(kCallbackNameOnEnrollResult);
+ Return<void> onEnrollResult(uint64_t, uint32_t, int32_t userId, uint32_t) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnEnrollResult, args);
return Void();
}
- Return<void> onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec<uint8_t>&) override {
- NotifyFromCallback(kCallbackNameOnAuthenticated);
+ Return<void> onAuthenticated(uint64_t, uint32_t, int32_t userId,
+ const hidl_vec<uint8_t>&) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnAuthenticated, args);
return Void();
}
- Return<void> onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override {
- NotifyFromCallback(kCallbackNameOnAcquired);
+ Return<void> onAcquired(uint64_t, int32_t userId, FaceAcquiredInfo, int32_t) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnAcquired, args);
return Void();
}
- Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
+ Return<void> onError(uint64_t, int32_t userId, FaceError error, int32_t) override {
FaceCallbackArgs args = {};
args.error = error;
+ args.userId = userId;
NotifyFromCallback(kCallbackNameOnError, args);
return Void();
}
@@ -103,8 +111,10 @@
return Void();
}
- Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
- NotifyFromCallback(kCallbackNameOnEnumerate);
+ Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnEnumerate, args);
return Void();
}
@@ -185,6 +195,7 @@
// onError should be called with a meaningful (nonzero) error.
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
@@ -205,6 +216,7 @@
// onError should be called with a meaningful (nonzero) error.
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
@@ -271,6 +283,7 @@
Return<Status> ret = mService->enumerate();
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_TRUE(res.no_timeout);
}
@@ -330,6 +343,7 @@
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
// make sure callback was invoked within kRevokeChallengeTimeout
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::CANCELED, res.args->error);
}
diff --git a/current.txt b/current.txt
index b398621..98cb792 100644
--- a/current.txt
+++ b/current.txt
@@ -589,9 +589,11 @@
ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
-34515afa2bb792d3c6d8495a5f5d907d179c8507ca5e55c10050d02ae1d516ef android.hardware.neuralnetworks@1.3::IDevice
+9e59fffceed0dd72a9799e04505db5f777bbbea1af0695ba4107ef6d967c6fda android.hardware.neuralnetworks@1.3::IDevice
+4a6c3b3556da951b4def21ba579a227c022980fe4465df6cdfbe20628fa75f5a android.hardware.neuralnetworks@1.3::IPreparedModel
+94e803236398bed1febb11cc21051bc42ec003700139b099d6c479e02a7ca3c3 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
b74fe72cfe438f50e772e6a307657ff449d5bde83c15dd1f140ff2edbe73499c android.hardware.neuralnetworks@1.3::types
-d3636ff9d5fef59f59f678887209156b2608d29f676fb1e600fe33b7e57a8a61 android.hardware.radio@1.5::types
+274fb1254a6d1a97824ec5c880eeefc0e410dc6d3a2a4c34052201169d2b7de0 android.hardware.radio@1.5::types
c8e81d912827a5d49b2ddcdc4eb4556c5d231a899a1dca879309e04210daa4a0 android.hardware.radio@1.5::IRadio
a62a93faf173b14a6175b683ebf61ffa568dc61f81e369d2dce7b1265e86cf2f android.hardware.radio@1.5::IRadioIndication
260ce05806d753d728f844d405e832179ed7d9b65986ec18fef3d21cf7285587 android.hardware.radio@1.5::IRadioResponse
diff --git a/neuralnetworks/1.3/Android.bp b/neuralnetworks/1.3/Android.bp
index 0615ec6..0b07a58 100644
--- a/neuralnetworks/1.3/Android.bp
+++ b/neuralnetworks/1.3/Android.bp
@@ -9,6 +9,8 @@
srcs: [
"types.hal",
"IDevice.hal",
+ "IPreparedModel.hal",
+ "IPreparedModelCallback.hal",
],
interfaces: [
"android.hardware.neuralnetworks@1.0",
diff --git a/neuralnetworks/1.3/IDevice.hal b/neuralnetworks/1.3/IDevice.hal
index ee36fb4..1295d6a 100644
--- a/neuralnetworks/1.3/IDevice.hal
+++ b/neuralnetworks/1.3/IDevice.hal
@@ -22,7 +22,7 @@
import @1.2::DeviceType;
import @1.2::Extension;
import @1.2::IDevice;
-import @1.2::IPreparedModelCallback;
+import IPreparedModelCallback;
/**
* This interface represents a device driver.
@@ -134,18 +134,18 @@
* not provided, or match the numModelCache returned from
* getNumberOfCacheFilesNeeded. The cache handles will be provided in
* the same order when retrieving the preparedModel from cache files
- * with prepareModelFromCache.
+ * with prepareModelFromCache_1_3.
* @param dataCache A vector of handles with each entry holding exactly one
* cache file descriptor for the constants' cache. The length of the
* vector must either be 0 indicating that caching information is not
* provided, or match the numDataCache returned from
* getNumberOfCacheFilesNeeded. The cache handles will be provided in
* the same order when retrieving the preparedModel from cache files
- * with prepareModelFromCache.
+ * with prepareModelFromCache_1_3.
* @param token A caching token of length Constant::BYTE_SIZE_OF_CACHE_TOKEN
* identifying the prepared model. The same token will be provided when
* retrieving the prepared model from the cache files with
- * prepareModelFromCache. Tokens should be chosen to have a low rate of
+ * prepareModelFromCache_1_3. Tokens should be chosen to have a low rate of
* collision for a particular application. The driver cannot detect a
* collision; a collision will result in a failed execution or in a
* successful execution that produces incorrect output values. If both
@@ -168,4 +168,83 @@
uint8_t[Constant:BYTE_SIZE_OF_CACHE_TOKEN] token,
IPreparedModelCallback callback)
generates (ErrorStatus status);
+
+ /**
+ * Creates a prepared model from cache files for execution.
+ *
+ * prepareModelFromCache_1_3 is used to retrieve a prepared model directly from
+ * cache files to avoid slow model compilation time. There are
+ * two types of cache file handles provided to the driver: model cache
+ * and data cache. For more information on the two types of cache handles,
+ * refer to getNumberOfCacheFilesNeeded.
+ *
+ * The file descriptors must be opened with read and write permission. A file may
+ * have any size, and the corresponding file descriptor may have any offset. The
+ * driver must truncate a file to zero size before writing to that file. The file
+ * descriptors may be closed by the client once the asynchronous preparation has
+ * finished. The driver must dup a file descriptor if it wants to get access to
+ * the cache file later.
+ *
+ * The model is prepared asynchronously with respect to the caller. The
+ * prepareModelFromCache_1_3 function must verify the inputs to the
+ * prepareModelFromCache_1_3 function are correct, and that the security-sensitive
+ * cache has not been modified since it was last written by the driver.
+ * If there is an error, or if compilation caching is not supported, or if the
+ * security-sensitive cache has been modified, prepareModelFromCache_1_3 must
+ * immediately invoke the callback with the appropriate ErrorStatus value and
+ * nullptr for the IPreparedModel, then return with the same ErrorStatus. If
+ * the inputs to the prepareModelFromCache_1_3 function are valid, the security-sensitive
+ * cache is not modified, and there is no error, prepareModelFromCache_1_3 must launch an
+ * asynchronous task to prepare the model in the background, and immediately return
+ * from prepareModelFromCache_1_3 with ErrorStatus::NONE. If the asynchronous task
+ * fails to launch, prepareModelFromCache_1_3 must immediately invoke the callback
+ * with ErrorStatus::GENERAL_FAILURE and nullptr for the IPreparedModel, then
+ * return with ErrorStatus::GENERAL_FAILURE.
+ *
+ * When the asynchronous task has finished preparing the model, it must
+ * immediately invoke the callback function provided as an input to
+ * prepareModelFromCache_1_3. If the model was prepared successfully, the
+ * callback object must be invoked with an error status of ErrorStatus::NONE
+ * and the produced IPreparedModel object. If an error occurred preparing
+ * the model, the callback object must be invoked with the appropriate
+ * ErrorStatus value and nullptr for the IPreparedModel.
+ *
+ * The only information that may be unknown to the model at this stage is
+ * the shape of the tensors, which may only be known at execution time. As
+ * such, some driver services may return partially prepared models, where
+ * the prepared model may only be finished when it is paired with a set of
+ * inputs to the model. Note that the same prepared model object may be
+ * used with different shapes of inputs on different (possibly concurrent)
+ * executions.
+ *
+ * @param modelCache A vector of handles with each entry holding exactly one
+ * cache file descriptor for the security-sensitive cache. The length of
+ * the vector must match the numModelCache returned from getNumberOfCacheFilesNeeded.
+ * The cache handles will be provided in the same order as with prepareModel_1_3.
+ * @param dataCache A vector of handles with each entry holding exactly one
+ * cache file descriptor for the constants' cache. The length of the vector
+ * must match the numDataCache returned from getNumberOfCacheFilesNeeded.
+ * The cache handles will be provided in the same order as with prepareModel_1_3.
+ * @param token A caching token of length Constant::BYTE_SIZE_OF_CACHE_TOKEN
+ * identifying the prepared model. It is the same token provided when saving
+ * the cache files with prepareModel_1_3. Tokens should be chosen
+ * to have a low rate of collision for a particular application. The driver
+ * cannot detect a collision; a collision will result in a failed execution
+ * or in a successful execution that produces incorrect output values.
+ * @param callback A callback object used to return the error status of
+ * preparing the model for execution and the prepared model if
+ * successful, nullptr otherwise. The callback object's notify function
+ * must be called exactly once, even if the model could not be prepared.
+ * @return status Error status of launching a task which prepares the model
+ * in the background; must be:
+ * - NONE if preparation task is successfully launched
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if caching is not supported or if there is an
+ * unspecified error
+ * - INVALID_ARGUMENT if one of the input arguments is invalid
+ */
+ prepareModelFromCache_1_3(vec<handle> modelCache, vec<handle> dataCache,
+ uint8_t[Constant:BYTE_SIZE_OF_CACHE_TOKEN] token,
+ IPreparedModelCallback callback)
+ generates (ErrorStatus status);
};
diff --git a/neuralnetworks/1.3/IPreparedModel.hal b/neuralnetworks/1.3/IPreparedModel.hal
new file mode 100644
index 0000000..c04809f
--- /dev/null
+++ b/neuralnetworks/1.3/IPreparedModel.hal
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 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.neuralnetworks@1.3;
+
+import @1.0::ErrorStatus;
+import @1.0::Request;
+import @1.2::MeasureTiming;
+import @1.2::IExecutionCallback;
+import @1.2::IPreparedModel;
+
+/**
+ * IPreparedModel describes a model that has been prepared for execution and
+ * is used to launch executions.
+ */
+interface IPreparedModel extends @1.2::IPreparedModel {
+ /**
+ * Launches an asynchronous execution on a prepared model.
+ *
+ * The execution is performed asynchronously with respect to the caller.
+ * execute_1_3 must verify the inputs to the function are correct. If there is
+ * an error, execute_1_3 must immediately invoke the callback with the
+ * appropriate ErrorStatus value, then return with the same ErrorStatus. If
+ * the inputs to the function are valid and there is no error, execute_1_3 must
+ * launch an asynchronous task to perform the execution in the background,
+ * and immediately return with ErrorStatus::NONE. If the asynchronous task
+ * fails to launch, execute_1_3 must immediately invoke the callback with
+ * ErrorStatus::GENERAL_FAILURE, then return with
+ * ErrorStatus::GENERAL_FAILURE.
+ *
+ * When the asynchronous task has finished its execution, it must
+ * immediately invoke the callback object provided as an input to the
+ * execute_1_3 function. This callback must be provided with the ErrorStatus of
+ * the execution.
+ *
+ * If the launch is successful, the caller must not change the content of
+ * any data object referenced by 'request' (described by the
+ * {@link @1.0::DataLocation} of a {@link @1.0::RequestArgument}) until the
+ * asynchronous task has invoked the callback object. The asynchronous task
+ * must not change the content of any of the data objects corresponding to
+ * 'request' inputs.
+ *
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and the inputs to the function
+ * are valid, then:
+ * - the execution should launch successfully (ErrorStatus::NONE): There
+ * must be no failure unless the device itself is in a bad state.
+ * - if at execution time every operation's input operands have legal
+ * values, the execution should complete successfully (ErrorStatus::NONE):
+ * There must be no failure unless the device itself is in a bad state.
+ *
+ * Any number of calls to the execute, execute_1_2, execute_1_3, and executeSynchronously
+ * functions, in any combination, may be made concurrently, even on the same
+ * IPreparedModel object.
+ *
+ * @param request The input and output information on which the prepared
+ * model is to be executed.
+ * @param measure Specifies whether or not to measure duration of the execution.
+ * The duration runs from the time the driver sees the call
+ * to the execute_1_3 function to the time the driver invokes
+ * the callback.
+ * @param callback A callback object used to return the error status of
+ * the execution. The callback object's notify function must
+ * be called exactly once, even if the execution was
+ * unsuccessful.
+ * @return status Error status of the call, must be:
+ * - NONE if task is successfully launched
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is
+ * not large enough to store the resultant values
+ * - INVALID_ARGUMENT if one of the input arguments is
+ * invalid
+ */
+ execute_1_3(Request request, MeasureTiming measure, IExecutionCallback callback)
+ generates (ErrorStatus status);
+};
diff --git a/neuralnetworks/1.3/IPreparedModelCallback.hal b/neuralnetworks/1.3/IPreparedModelCallback.hal
new file mode 100644
index 0000000..ff295a2
--- /dev/null
+++ b/neuralnetworks/1.3/IPreparedModelCallback.hal
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.neuralnetworks@1.3;
+
+import @1.0::ErrorStatus;
+import @1.2::IPreparedModelCallback;
+import IPreparedModel;
+
+/**
+ * IPreparedModelCallback must be used to return a prepared model produced by an
+ * asynchronous task launched from IDevice::prepareModel.
+ */
+interface IPreparedModelCallback extends @1.2::IPreparedModelCallback {
+
+ /**
+ * There are three notify methods declared for the IPreparedModelCallback
+ * interface: notify_1_3, notify_1_2, and notify. One of the three
+ * notify methods must be invoked immediately after the asynchronous
+ * task holding this callback has finished preparing the model. If the model was
+ * successfully prepared, one of the notify methods must be invoked with
+ * ErrorStatus::NONE and the prepared model. If the model was not able to be
+ * successfully prepared, one of the notify methods must be invoked with the
+ * appropriate ErrorStatus and nullptr as the IPreparedModel. If the asynchronous
+ * task holding this callback fails to launch or if the model provided to
+ * IDevice::prepareModel is invalid, one of the notify methods must be invoked
+ * with the appropriate error as well as nullptr for the IPreparedModel.
+ *
+ * @param status Error status returned from the asynchronous model
+ * preparation task; must be:
+ * - NONE if the asynchronous task successfully prepared the
+ * model
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an
+ * unspecified error
+ * - INVALID_ARGUMENT if one of the input arguments to
+ * prepareModel is invalid
+ * @param preparedModel A model that has been asynchronously prepared for
+ * execution. If the model was unable to be prepared
+ * due to an error, nullptr must be passed in place of
+ * the IPreparedModel object.
+ */
+ oneway notify_1_3(ErrorStatus status, IPreparedModel preparedModel);
+};
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 0f2720e..e2795de 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -14,6 +14,24 @@
// limitations under the License.
//
+cc_library_static {
+ name: "VtsHalNeuralNetworksV1_3Callbacks",
+ defaults: ["VtsHalTargetTestDefaults"],
+ export_include_dirs: ["include"],
+ srcs: [
+ "Callbacks.cpp",
+ ],
+ static_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hardware.neuralnetworks@1.2",
+ "android.hardware.neuralnetworks@1.3",
+ ],
+ header_libs: [
+ "libbase_headers",
+ ]
+}
+
cc_test {
name: "VtsHalNeuralnetworksV1_3TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
@@ -44,6 +62,7 @@
"libneuralnetworks_utils",
"VtsHalNeuralNetworksV1_0_utils",
"VtsHalNeuralNetworksV1_2Callbacks",
+ "VtsHalNeuralNetworksV1_3Callbacks",
],
whole_static_libs: [
"neuralnetworks_generated_V1_0_example",
diff --git a/neuralnetworks/1.3/vts/functional/Callbacks.cpp b/neuralnetworks/1.3/vts/functional/Callbacks.cpp
new file mode 100644
index 0000000..4f08e72
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/Callbacks.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 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 "Callbacks"
+
+#include "1.3/Callbacks.h"
+
+#include <android-base/logging.h>
+
+#include <limits>
+
+namespace android::hardware::neuralnetworks::V1_3::implementation {
+
+using V1_0::ErrorStatus;
+
+// PreparedModelCallback methods begin here
+
+Return<void> PreparedModelCallback::notify(ErrorStatus errorStatus,
+ const sp<V1_0::IPreparedModel>& preparedModel) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return Void();
+ }
+
+ // store results and mark as notified
+ mErrorStatus = errorStatus;
+ mPreparedModel = preparedModel;
+ mNotified = true;
+ }
+
+ mCondition.notify_all();
+ return Void();
+}
+
+Return<void> PreparedModelCallback::notify_1_2(ErrorStatus errorStatus,
+ const sp<V1_2::IPreparedModel>& preparedModel) {
+ return notify(errorStatus, preparedModel);
+}
+
+Return<void> PreparedModelCallback::notify_1_3(ErrorStatus errorStatus,
+ const sp<V1_3::IPreparedModel>& preparedModel) {
+ return notify(errorStatus, preparedModel);
+}
+
+void PreparedModelCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
+}
+
+ErrorStatus PreparedModelCallback::getStatus() const {
+ wait();
+ return mErrorStatus;
+}
+
+sp<V1_0::IPreparedModel> PreparedModelCallback::getPreparedModel() const {
+ wait();
+ return mPreparedModel;
+}
+
+} // namespace android::hardware::neuralnetworks::V1_3::implementation
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index 0ac4738..d8a7534 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -28,7 +28,7 @@
#include <random>
#include <thread>
-#include "1.2/Callbacks.h"
+#include "1.3/Callbacks.h"
#include "GeneratedTestHarness.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
@@ -48,12 +48,11 @@
namespace android::hardware::neuralnetworks::V1_3::vts::functional {
using namespace test_helper;
+using implementation::PreparedModelCallback;
using V1_0::ErrorStatus;
using V1_1::ExecutionPreference;
using V1_2::Constant;
-using V1_2::IPreparedModel;
using V1_2::OperationType;
-using V1_2::implementation::PreparedModelCallback;
namespace float32_model {
@@ -231,7 +230,7 @@
ASSERT_NE(kDevice.get(), nullptr);
// Create cache directory. The cache directory and a temporary cache file is always created
- // to test the behavior of prepareModelFromCache, even when caching is not supported.
+ // to test the behavior of prepareModelFromCache_1_3, even when caching is not supported.
char cacheDirTemp[] = "/data/local/tmp/TestCompilationCachingXXXXXX";
char* cacheDir = mkdtemp(cacheDirTemp);
ASSERT_NE(cacheDir, nullptr);
@@ -370,7 +369,7 @@
// Launch prepare model from cache.
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
hidl_array<uint8_t, sizeof(mToken)> cacheToken(mToken);
- Return<ErrorStatus> prepareLaunchStatus = kDevice->prepareModelFromCache(
+ Return<ErrorStatus> prepareLaunchStatus = kDevice->prepareModelFromCache_1_3(
modelCache, dataCache, cacheToken, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
if (static_cast<ErrorStatus>(prepareLaunchStatus) != ErrorStatus::NONE) {
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
index 8a7ed24..325d641 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
@@ -29,6 +29,8 @@
#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
#include <android/hardware/neuralnetworks/1.2/types.h>
#include <android/hardware/neuralnetworks/1.3/IDevice.h>
+#include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.h>
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
@@ -42,6 +44,7 @@
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
+#include "1.3/Callbacks.h"
#include "ExecutionBurstController.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
@@ -52,20 +55,19 @@
using namespace test_helper;
using hidl::memory::V1_0::IMemory;
+using implementation::PreparedModelCallback;
using V1_0::DataLocation;
using V1_0::ErrorStatus;
using V1_0::OperandLifeTime;
using V1_0::Request;
using V1_1::ExecutionPreference;
using V1_2::Constant;
-using V1_2::IPreparedModel;
using V1_2::MeasureTiming;
using V1_2::OperationType;
using V1_2::OutputShape;
using V1_2::SymmPerChannelQuantParams;
using V1_2::Timing;
using V1_2::implementation::ExecutionCallback;
-using V1_2::implementation::PreparedModelCallback;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
@@ -179,7 +181,7 @@
static Return<ErrorStatus> ExecutePreparedModel(const sp<IPreparedModel>& preparedModel,
const Request& request, MeasureTiming measure,
sp<ExecutionCallback>& callback) {
- return preparedModel->execute_1_2(request, measure, callback);
+ return preparedModel->execute_1_3(request, measure, callback);
}
static Return<ErrorStatus> ExecutePreparedModel(const sp<IPreparedModel>& preparedModel,
const Request& request, MeasureTiming measure,
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
index b9277cf..45cff5b 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
@@ -17,8 +17,8 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_3_GENERATED_TEST_HARNESS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_3_GENERATED_TEST_HARNESS_H
-#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.3/IDevice.h>
+#include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <functional>
#include <vector>
@@ -55,10 +55,9 @@
Model createModel(const test_helper::TestModel& testModel);
-void PrepareModel(const sp<IDevice>& device, const Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
+void PrepareModel(const sp<IDevice>& device, const Model& model, sp<IPreparedModel>* preparedModel);
-void EvaluatePreparedModel(const sp<V1_2::IPreparedModel>& preparedModel,
+void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel,
const test_helper::TestModel& testModel, bool testDynamicOutputShape);
} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
index 2c97294..7df8046 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
@@ -40,7 +40,6 @@
using V1_2::FmqResultDatum;
using V1_2::IBurstCallback;
using V1_2::IBurstContext;
-using V1_2::IPreparedModel;
using V1_2::MeasureTiming;
using V1_2::Timing;
using ExecutionBurstCallback = ExecutionBurstController::ExecutionBurstCallback;
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 44b32a9..1ff02dc 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -17,20 +17,19 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include "1.0/Utils.h"
-#include "1.2/Callbacks.h"
+#include "1.3/Callbacks.h"
#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+using implementation::PreparedModelCallback;
using V1_0::ErrorStatus;
using V1_0::OperandLifeTime;
using V1_1::ExecutionPreference;
-using V1_2::IPreparedModel;
using V1_2::OperationType;
using V1_2::OperationTypeRange;
using V1_2::SymmPerChannelQuantParams;
-using V1_2::implementation::PreparedModelCallback;
using HidlToken =
hidl_array<uint8_t, static_cast<uint32_t>(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
@@ -61,7 +60,7 @@
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, prepareReturnStatus);
- sp<IPreparedModel> preparedModel = getPreparedModel_1_2(preparedModelCallback);
+ sp<IPreparedModel> preparedModel = getPreparedModel_1_3(preparedModelCallback);
ASSERT_EQ(nullptr, preparedModel.get());
}
diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
index c00512c..2cf30d5 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
@@ -29,7 +29,6 @@
using V1_0::ErrorStatus;
using V1_0::Request;
-using V1_2::IPreparedModel;
using V1_2::MeasureTiming;
using V1_2::OutputShape;
using V1_2::Timing;
@@ -61,11 +60,11 @@
// asynchronous
{
- SCOPED_TRACE(message + " [execute_1_2]");
+ SCOPED_TRACE(message + " [execute_1_3]");
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
Return<ErrorStatus> executeLaunchStatus =
- preparedModel->execute_1_2(request, measure, executionCallback);
+ preparedModel->execute_1_3(request, measure, executionCallback);
ASSERT_TRUE(executeLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeLaunchStatus));
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
index 4f0e150..625913d 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
@@ -21,8 +21,8 @@
#include <hidl/ServiceManagement.h>
#include <string>
#include <utility>
-#include "1.0/Callbacks.h"
#include "1.0/Utils.h"
+#include "1.3/Callbacks.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
@@ -30,11 +30,10 @@
using HidlToken =
hidl_array<uint8_t, static_cast<uint32_t>(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+using implementation::PreparedModelCallback;
using V1_0::ErrorStatus;
using V1_0::Request;
using V1_1::ExecutionPreference;
-using V1_2::IPreparedModel;
-using V1_2::implementation::PreparedModelCallback;
// internal helper function
void createPreparedModel(const sp<IDevice>& device, const Model& model,
@@ -64,7 +63,7 @@
// retrieve prepared model
preparedModelCallback->wait();
const ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- *preparedModel = getPreparedModel_1_2(preparedModelCallback);
+ *preparedModel = getPreparedModel_1_3(preparedModelCallback);
// The getSupportedOperations_1_3 call returns a list of operations that are
// guaranteed not to fail if prepareModel_1_3 is called, and
@@ -165,7 +164,7 @@
INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
-sp<IPreparedModel> getPreparedModel_1_2(const sp<PreparedModelCallback>& callback) {
+sp<IPreparedModel> getPreparedModel_1_3(const sp<PreparedModelCallback>& callback) {
sp<V1_0::IPreparedModel> preparedModelV1_0 = callback->getPreparedModel();
return IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
}
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
index fc654ce..8cb42d4 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
@@ -17,12 +17,12 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_3_VTS_HAL_NEURALNETWORKS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_3_VTS_HAL_NEURALNETWORKS_H
-#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.3/IDevice.h>
+#include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <gtest/gtest.h>
#include "1.0/Utils.h"
-#include "1.2/Callbacks.h"
+#include "1.3/Callbacks.h"
namespace android::hardware::neuralnetworks::V1_3::vts::functional {
@@ -47,11 +47,10 @@
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
+ sp<IPreparedModel>* preparedModel);
// Utility function to get PreparedModel from callback and downcast to V1_2.
-sp<V1_2::IPreparedModel> getPreparedModel_1_2(
- const sp<V1_2::implementation::PreparedModelCallback>& callback);
+sp<IPreparedModel> getPreparedModel_1_3(const sp<implementation::PreparedModelCallback>& callback);
} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/include/1.3/Callbacks.h b/neuralnetworks/1.3/vts/functional/include/1.3/Callbacks.h
new file mode 100644
index 0000000..fb19a84
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/include/1.3/Callbacks.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 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_NEURALNETWORKS_V1_3_CALLBACKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_3_CALLBACKS_H
+
+#include <android-base/thread_annotations.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.h>
+#include <hidl/Status.h>
+#include <condition_variable>
+#include <mutex>
+
+/*
+ * The Callback classes are used internally by the NeuralNetworks runtime to
+ * synchronize between different threads. An asynchronous task is launched
+ * paired with a callback object. When a client thread requires the output being
+ * generated by the asynchronous task, the client thread can wait for the result
+ * and be blocked until it has completed. Any wait may safely be called
+ * concurrently, even on the same callback object. When the asynchronous task
+ * has finished its workload, it must immediately call "notify*". If the
+ * asynchronous task has failed to launch, the function that tried to launch the
+ * asynchronous task must immediately call "notify*". This "notify*" call
+ * awakens any client threads waiting on the callback object.
+ *
+ * These classes exist to enable synchronization across HIDL. When
+ * synchronization is only required in the same process, consider using
+ * std::future, std::mutex, std::condition_variable, or std::experimental::latch
+ * instead.
+ */
+
+namespace android::hardware::neuralnetworks::V1_3::implementation {
+
+/**
+ * The PreparedModelCallback class is used to receive the error status of
+ * preparing a model as well as the prepared model from a task executing
+ * asynchronously with respect to the runtime. If a calling thread calls wait
+ * or get* on a PreparedModelCallback object and the corresponding asynchronous
+ * task has not finished preparing the model, the calling thread will block
+ * until the asynchronous task has called notify*.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify* are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IDevice::prepareModel*.
+ */
+class PreparedModelCallback : public IPreparedModelCallback {
+ public:
+ /**
+ * IPreparedModelCallback::notify marks the callback object with the return
+ * status of the asynchronous model preparation along with the prepared
+ * model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
+ * or IPreparedModelCallback::notify_1_3 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @param preparedModel Returned model that has been prepared for execution,
+ * nullptr if the model was unable to be prepared.
+ */
+ Return<void> notify(V1_0::ErrorStatus status,
+ const sp<V1_0::IPreparedModel>& preparedModel) override;
+
+ /**
+ * IPreparedModelCallback::notify_1_2 marks the callback object with the
+ * return status of the asynchronous model preparation along with the
+ * prepared model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
+ * or IPreparedModelCallback::notify_1_3 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @param preparedModel Returned model that has been prepared for execution,
+ * nullptr if the model was unable to be prepared.
+ */
+ Return<void> notify_1_2(V1_0::ErrorStatus status,
+ const sp<V1_2::IPreparedModel>& preparedModel) override;
+
+ /**
+ * IPreparedModelCallback::notify_1_3 marks the callback object with the
+ * return status of the asynchronous model preparation along with the
+ * prepared model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
+ * or IPreparedModelCallback::notify_1_3 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @param preparedModel Returned model that has been prepared for execution,
+ * nullptr if the model was unable to be prepared.
+ */
+ Return<void> notify_1_3(V1_0::ErrorStatus status,
+ const sp<V1_3::IPreparedModel>& preparedModel) override;
+
+ /**
+ * PreparedModelCallback::wait blocks until notify* has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by IDevice::prepareModel*. If IDevice::prepareModel* has not finished
+ * asynchronously preparing the model, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * @return status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ */
+ V1_0::ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the model that has been prepared for execution from the
+ * asynchronous task launched by IDevice::prepareModel*. If
+ * IDevice::prepareModel* has not finished asynchronously preparing the
+ * model, this call will block until the asynchronous task notifies the
+ * object.
+ *
+ * @return preparedModel Returned model that has been prepared for
+ * execution, nullptr if the model was unable to be prepared.
+ */
+ sp<V1_0::IPreparedModel> getPreparedModel() const;
+
+ private:
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ V1_0::ErrorStatus mErrorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
+ sp<V1_0::IPreparedModel> mPreparedModel;
+};
+
+} // namespace android::hardware::neuralnetworks::V1_3::implementation
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_3_CALLBACKS_H
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index 216ca1f..2441b65 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -52,9 +52,11 @@
RSRQ = 4,
/**
* Reference Signal Signal to Noise Ratio
- * Range: -20 dB to -30 dB;
+ * Range: -20 dB to 30 dB;
* Used RAN: EUTRAN
- * Reference: 3GPP TS 36.101 8.1.1
+ * Note: this field is optional; how to support it can be decided by the
+ * corresponding vendor. Though the response code is not enforced,
+ * vendor's implementation must ensure this interface not crashing.
*/
RSSNR = 5,
/**
@@ -111,4 +113,4 @@
* Next-Generation Radio Access Network (NGRAN)
*/
NGRAN = 6,
-};
\ No newline at end of file
+};
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 650ede4..d173411 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -179,10 +179,6 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
-
- ALOGI("setSignalStrengthReportingCriteria_1_5_Eutran, rspInfo.error = %s\n",
- toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
}
/*
@@ -279,4 +275,4 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
-}
\ No newline at end of file
+}
diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
index a771100..1acc8e6 100644
--- a/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
+++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
@@ -5,7 +5,7 @@
<version>2.0</version>
<interface>
<name>ISensors</name>
- <instance>multihal</instance>
+ <instance>default</instance>
</interface>
</hal>
</manifest>
diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp
new file mode 100644
index 0000000..ef9b39b
--- /dev/null
+++ b/tests/extension/vibrator/aidl/Android.bp
@@ -0,0 +1,29 @@
+aidl_interface {
+ // This is an example test interface showing how to add functionality
+ // with setExtension/getExtension
+ name: "test-vintf-vibrator-ext",
+ vendor_available: true,
+ srcs: [
+ // Using android.hardware as the package because this is in
+ // hardware/interfaces. For custom interfaces, normally you
+ // would use a different package.
+ "android/hardware/tests/extension/vibrator/Directionality.aidl",
+ "android/hardware/tests/extension/vibrator/ICustomVibrator.aidl",
+ "android/hardware/tests/extension/vibrator/VendorEffect.aidl",
+ ],
+
+ // This is agreeing to keep the interface stable.
+ stability: "vintf",
+
+ // This happens to use types from a core interface, so we import it, but
+ // this won't always be needed.
+ imports: [
+ "vintf-vibrator",
+ ],
+
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
+}
diff --git a/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl
new file mode 100644
index 0000000..72bfd66
--- /dev/null
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 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.tests.extension.vibrator;
+
+/**
+ * Can add custom enums. If these need to be extended further, new values can
+ * simply be added.
+ */
+@Backing(type="int")
+@VintfStability
+enum Directionality {
+ NONE,
+ /** vibrations should be transverse wrt primary screen */
+ TRANSVERSE,
+ /** vibrations should be longitudinal wrt primary screen */
+ LONGITUDINAL,
+}
diff --git a/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
new file mode 100644
index 0000000..0b21f46
--- /dev/null
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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.tests.extension.vibrator;
+
+// it's fine to use types from other interfaces
+import android.hardware.vibrator.IVibratorCallback;
+import android.hardware.tests.extension.vibrator.Directionality;
+import android.hardware.tests.extension.vibrator.VendorEffect;
+
+/**
+ * This is an example of an AIDL interface extension. Notice that it does not
+ * inherit from any other extension. Instead, it will be tagged onto that
+ * extension at runtime.
+ */
+@VintfStability
+interface ICustomVibrator {
+ /**
+ * Avoid conflicting with vendor properties. Giving this as an example
+ * because the core vibrator interface uses capabilities. In reality,
+ * since this is only one capability, it's probably not needed to construct
+ * a bitfield.
+ *
+ * This is for longitudinal/transverse waves, see setDirectionality.
+ */
+ const int CAP_VENDOR_DIRECTIONALITY = 1 << 0;
+
+ /**
+ * Any new methods can be added, this returns CAP_VENDOR_*.
+ */
+ int getVendorCapabilities();
+
+ /**
+ * Arbitrary new functionality can be added.
+ */
+ void setDirectionality(Directionality directionality);
+
+ /**
+ * Perform a custom vendor effect. Note, this is a separate effect enum to
+ * avoid conflicting with core types.
+ */
+ int perform(VendorEffect effect, IVibratorCallback callback);
+}
diff --git a/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl
new file mode 100644
index 0000000..968532c
--- /dev/null
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.tests.extension.vibrator;
+
+/**
+ * Extending enum separately to avoid conflicts w/ upstream.
+ */
+@Backing(type="int")
+@VintfStability
+enum VendorEffect {
+ CRACKLE,
+ WIGGLE,
+}
diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp
new file mode 100644
index 0000000..f7b71f7
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/Android.bp
@@ -0,0 +1,26 @@
+
+// This example client is written as a test, but it is executing from a system
+// context. All this code would look the same if it was running in system
+// server for example.
+
+cc_test {
+ name: "test-vintf-vibrator-ext-client",
+ srcs: [
+ // system code has the option to use the unstable C++ libbinder API
+ // or the NDK one. For maximum code portability, using the ndk client
+ // makes the most sense, but both are provided here as an example.
+ "test-cpp-client.cpp",
+ "test-ndk-client.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "vintf-vibrator-cpp",
+ "test-vintf-vibrator-ext-cpp",
+
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ "test-vintf-vibrator-ext-ndk_platform",
+ ],
+}
+
diff --git a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
new file mode 100644
index 0000000..f6f5537
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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 <android/hardware/tests/extension/vibrator/ICustomVibrator.h>
+#include <android/hardware/vibrator/IVibrator.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <gtest/gtest.h>
+
+using android::IBinder;
+using android::IInterface;
+using android::interface_cast;
+using android::OK;
+using android::sp;
+using android::waitForVintfService;
+using android::hardware::tests::extension::vibrator::Directionality;
+using android::hardware::tests::extension::vibrator::ICustomVibrator;
+using android::hardware::vibrator::IVibrator;
+
+TEST(Cpp, CallRootMethod) {
+ sp<IVibrator> vib = waitForVintfService<IVibrator>();
+ ASSERT_NE(nullptr, vib.get());
+ ASSERT_TRUE(vib->off().isOk());
+}
+
+TEST(Cpp, CallExtMethod) {
+ // normally you would want to cache this
+ sp<IVibrator> vib = waitForVintfService<IVibrator>();
+ ASSERT_NE(nullptr, vib.get());
+
+ // getting the extension
+ sp<IBinder> ext;
+ ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext));
+ sp<ICustomVibrator> cvib = interface_cast<ICustomVibrator>(ext);
+ ASSERT_NE(nullptr, cvib.get());
+
+ // calling extension method
+ ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
+}
diff --git a/tests/extension/vibrator/aidl/client/test-ndk-client.cpp b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
new file mode 100644
index 0000000..c846495
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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 <aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/binder_manager.h>
+
+#include <gtest/gtest.h>
+
+using aidl::android::hardware::tests::extension::vibrator::Directionality;
+using aidl::android::hardware::tests::extension::vibrator::ICustomVibrator;
+using aidl::android::hardware::vibrator::IVibrator;
+using ndk::SpAIBinder;
+
+static const std::string kInstance = std::string() + IVibrator::descriptor + "/default";
+
+TEST(Ndk, CallRootMethod) {
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ ASSERT_NE(nullptr, vibBinder.get());
+ std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
+ ASSERT_NE(nullptr, vib.get());
+ ASSERT_TRUE(vib->off().isOk());
+}
+
+TEST(Ndk, CallExtMethod) {
+ // normally you would want to cache this
+ //
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ ASSERT_NE(nullptr, vibBinder.get());
+ std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
+ ASSERT_NE(nullptr, vib.get());
+
+ // getting the extension
+ SpAIBinder cvibBinder;
+ ASSERT_EQ(STATUS_OK, AIBinder_getExtension(vibBinder.get(), cvibBinder.getR()));
+ ASSERT_NE(nullptr, cvibBinder.get());
+ std::shared_ptr<ICustomVibrator> cvib = ICustomVibrator::fromBinder(cvibBinder);
+ ASSERT_NE(nullptr, cvib.get());
+
+ // calling extension method
+ ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
+}
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
new file mode 100644
index 0000000..9869657
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -0,0 +1,25 @@
+cc_binary {
+ name: "android.hardware.tests.extension.vibrator-service.example",
+ relative_install_path: "hw",
+ // normally you implement a service directly, but we are using an implementation
+ // from a library to attach our extension to.
+ static_libs: [
+ "libvibratorexampleimpl",
+ ],
+
+ // need to add this in the manifest and to init as well to use, see
+ // android.hardware.vibrator-service.example. This binary is being tested
+ // by running it manually as root.
+
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "CustomVibrator.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ "test-vintf-vibrator-ext-ndk_platform",
+ ],
+}
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
new file mode 100644
index 0000000..2f3dfcb
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 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 "CustomVibrator.h"
+
+#include <android-base/logging.h>
+#include <thread>
+
+namespace aidl::android::hardware::tests::extension::vibrator {
+
+ndk::ScopedAStatus CustomVibrator::getVendorCapabilities(int32_t* _aidl_return) {
+ *_aidl_return = ICustomVibrator::CAP_VENDOR_DIRECTIONALITY;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus CustomVibrator::setDirectionality(Directionality directionality) {
+ LOG(INFO) << "Custom vibrator set directionality";
+ // do something cool in hardware
+ (void)directionality;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus CustomVibrator::perform(VendorEffect effect,
+ const std::shared_ptr<IVibratorCallback>& callback,
+ int32_t* _aidl_return) {
+ LOG(INFO) << "Custom vibrator perform";
+
+ if (effect != VendorEffect::CRACKLE && effect != VendorEffect::WIGGLE) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ constexpr size_t kEffectMillis = 100;
+
+ if (callback != nullptr) {
+ std::thread([=] {
+ LOG(INFO) << "Starting vendor perform on another thread";
+ usleep(kEffectMillis * 1000);
+ LOG(INFO) << "Notifying vendor perform complete";
+ callback->onComplete();
+ }).detach();
+ }
+
+ *_aidl_return = kEffectMillis;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.h b/tests/extension/vibrator/aidl/default/CustomVibrator.h
new file mode 100644
index 0000000..6dc5743
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tests/extension/vibrator/BnCustomVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibratorCallback.h>
+
+namespace aidl::android::hardware::tests::extension::vibrator {
+
+using aidl::android::hardware::vibrator::IVibratorCallback;
+
+class CustomVibrator : public BnCustomVibrator {
+ ndk::ScopedAStatus getVendorCapabilities(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus setDirectionality(Directionality directionality) override;
+ ndk::ScopedAStatus perform(VendorEffect effect,
+ const std::shared_ptr<IVibratorCallback>& callback,
+ int32_t* _aidl_return) override;
+};
+
+} // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/service.cpp b/tests/extension/vibrator/aidl/default/service.cpp
new file mode 100644
index 0000000..16290df
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/service.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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 <vibrator-impl/Vibrator.h>
+#include "CustomVibrator.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::tests::extension::vibrator::CustomVibrator;
+using aidl::android::hardware::vibrator::Vibrator;
+
+int main() {
+ // these are threads in addition to the one we are joining below, so this
+ // service will have a single thread
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ // making the core service
+ std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>();
+ ndk::SpAIBinder vibBinder = vib->asBinder();
+
+ // making the extension service
+ std::shared_ptr<CustomVibrator> cvib = ndk::SharedRefBase::make<CustomVibrator>();
+
+ // need to attach the extension to the same binder we will be registering
+ CHECK(STATUS_OK == AIBinder_setExtension(vibBinder.get(), cvib->asBinder().get()));
+
+ const std::string instance = std::string() + Vibrator::descriptor + "/default";
+ CHECK(STATUS_OK == AServiceManager_addService(vibBinder.get(), instance.c_str()));
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index f399887..dc8867f 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -1,3 +1,19 @@
+cc_library_static {
+ name: "libvibratorexampleimpl",
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ ],
+ export_include_dirs: ["include"],
+ srcs: ["Vibrator.cpp"],
+ visibility: [
+ ":__subpackages__",
+ "//hardware/interfaces/tests/extension/vibrator:__subpackages__",
+ ],
+}
+
cc_binary {
name: "android.hardware.vibrator-service.example",
relative_install_path: "hw",
@@ -9,5 +25,8 @@
"libbinder_ndk",
"vintf-vibrator-ndk_platform",
],
- srcs: ["main.cpp", "Vibrator.cpp"],
+ static_libs: [
+ "libvibratorexampleimpl",
+ ],
+ srcs: ["main.cpp"],
}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 18be1a6..09cd234 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Vibrator.h"
+#include "vibrator-impl/Vibrator.h"
#include <android-base/logging.h>
#include <thread>
diff --git a/vibrator/aidl/default/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
similarity index 100%
rename from vibrator/aidl/default/Vibrator.h
rename to vibrator/aidl/default/include/vibrator-impl/Vibrator.h
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index d1619ff..ebb0905 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Vibrator.h"
+#include "vibrator-impl/Vibrator.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>