Merge "example AIDL HAL extension"

am: 028bb37546

Change-Id: Ie87d98bfcdf1f593efc7cf4ca0220794d42e0caa
This commit is contained in:
Steven Moreland
2019-11-19 15:14:30 -08:00
committed by android-build-merger
15 changed files with 461 additions and 3 deletions

View File

@@ -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,
},
},
}

View File

@@ -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,
}

View File

@@ -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);
}

View File

@@ -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,
}

View File

@@ -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",
],
}

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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",
],
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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"],
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "Vibrator.h"
#include "vibrator-impl/Vibrator.h"
#include <android-base/logging.h>
#include <thread>

View File

@@ -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>