diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp new file mode 100644 index 0000000000..ef9b39bd87 --- /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 0000000000..72bfd667a9 --- /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 0000000000..0b21f463e1 --- /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 0000000000..968532ce23 --- /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 0000000000..f7b71f79f0 --- /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 0000000000..f6f5537104 --- /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 +#include +#include +#include +#include + +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 vib = waitForVintfService(); + ASSERT_NE(nullptr, vib.get()); + ASSERT_TRUE(vib->off().isOk()); +} + +TEST(Cpp, CallExtMethod) { + // normally you would want to cache this + sp vib = waitForVintfService(); + ASSERT_NE(nullptr, vib.get()); + + // getting the extension + sp ext; + ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext)); + sp cvib = interface_cast(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 0000000000..c846495984 --- /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 +#include +#include + +#include + +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 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 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 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 0000000000..9869657114 --- /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 0000000000..2f3dfcb27f --- /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 +#include + +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& 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 0000000000..6dc57439f5 --- /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 +#include + +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& 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 0000000000..16290df826 --- /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 +#include "CustomVibrator.h" + +#include +#include +#include + +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 vib = ndk::SharedRefBase::make(); + ndk::SpAIBinder vibBinder = vib->asBinder(); + + // making the extension service + std::shared_ptr cvib = ndk::SharedRefBase::make(); + + // 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 f3998872b2..dc8867fadf 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 @@ cc_binary { "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 18be1a6140..09cd2345bf 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 #include 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 d1619ff314..ebb0905a3a 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 #include