upload android base code part1

This commit is contained in:
August 2018-08-08 15:50:00 +08:00
parent e02f198e2d
commit 0a1de6c4b3
48159 changed files with 9071466 additions and 0 deletions

View file

@ -0,0 +1,24 @@
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
BasedOnStyle: Google
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
AllowShortFunctionsOnASingleLine: Inline
ColumnLimit: 100
TabWidth: 4
UseTab: Never
IndentWidth: 4

View file

@ -0,0 +1,10 @@
// This is an autogenerated file, do not edit.
subdirs = [
"displayservice/1.0",
"displayservice/1.0/vts/functional",
"schedulerservice/1.0",
"sensorservice/1.0",
"sensorservice/1.0/vts/functional",
"sensorservice/libsensorndkbridge",
"vr/composer/1.0",
]

View file

@ -0,0 +1,5 @@
[Options]
ignore_merged_commits = true
[Builtin Hooks]
clang_format = true

View file

@ -0,0 +1,19 @@
# Do not change this file except to add new interfaces. Changing
# pre-existing interfaces will fail VTS and break framework-only OTAs
# Framework HALs released in Android O
956ce5e409246c35b20ed16c64fdca3ef225412cc7fed06723a835d1ef9c88e5 android.frameworks.schedulerservice@1.0::ISchedulingPolicyService
3a62db403ef1f53a9b52a64d20be550537883e7cdb5a2569df755f5b2c7584b3 android.frameworks.sensorservice@1.0::IDirectReportChannel
c5d28aaea039b81a4a1309134564f55df3aaa964e992870aa9cd5ffd201541eb android.frameworks.sensorservice@1.0::IEventQueue
6f20cd7b412b278a54a423fb94f5e470087fbf6b13a3aa7dab14b3b2f2593dd4 android.frameworks.sensorservice@1.0::IEventQueueCallback
24bf4ab7c7e0d7eb8dce8eb1ac4ea7bd1cc95c44779fb23e137d3e87a15fac7d android.frameworks.sensorservice@1.0::ISensorManager
159f1a3fbb0ef043f4c4b31fc418ba40e75030a10f249bc2d39df88da82317b9 android.frameworks.sensorservice@1.0::types
3b9e26d665f3aa48c55ba17a74227a304690de21d309aaecf4877a97d7de5f34 android.frameworks.vr.composer@1.0::IVrComposerClient
# Framework HALs released in Android O MR1
6061e127a7e6b09d5b241485f2b37d0ea51d6fbfcc9cb905ef708db50100d0d2 android.frameworks.displayservice@1.0::IDisplayEventReceiver
a5dab2e6528095ccf4e9ae7e54e6e36ffe3dc0e1133fa3f9197f0b36216e09eb android.frameworks.displayservice@1.0::IDisplayService
5d4901c7f86a9e198b8d14e6e1de2fd819804db482b881dcf6230050f1dfdf34 android.frameworks.displayservice@1.0::IEventCallback
d80cdd518a48e1ff49f4776c7ea407b9be8d451510ff2cb8e57b2286f623496e android.frameworks.displayservice@1.0::types

View file

@ -0,0 +1,80 @@
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "android.frameworks.displayservice@1.0_hal",
srcs: [
"types.hal",
"IDisplayEventReceiver.hal",
"IDisplayService.hal",
"IEventCallback.hal",
],
}
genrule {
name: "android.frameworks.displayservice@1.0_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.frameworks:frameworks/hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.displayservice@1.0",
srcs: [
":android.frameworks.displayservice@1.0_hal",
],
out: [
"android/frameworks/displayservice/1.0/types.cpp",
"android/frameworks/displayservice/1.0/DisplayEventReceiverAll.cpp",
"android/frameworks/displayservice/1.0/DisplayServiceAll.cpp",
"android/frameworks/displayservice/1.0/EventCallbackAll.cpp",
],
}
genrule {
name: "android.frameworks.displayservice@1.0_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.frameworks:frameworks/hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.displayservice@1.0",
srcs: [
":android.frameworks.displayservice@1.0_hal",
],
out: [
"android/frameworks/displayservice/1.0/types.h",
"android/frameworks/displayservice/1.0/hwtypes.h",
"android/frameworks/displayservice/1.0/IDisplayEventReceiver.h",
"android/frameworks/displayservice/1.0/IHwDisplayEventReceiver.h",
"android/frameworks/displayservice/1.0/BnHwDisplayEventReceiver.h",
"android/frameworks/displayservice/1.0/BpHwDisplayEventReceiver.h",
"android/frameworks/displayservice/1.0/BsDisplayEventReceiver.h",
"android/frameworks/displayservice/1.0/IDisplayService.h",
"android/frameworks/displayservice/1.0/IHwDisplayService.h",
"android/frameworks/displayservice/1.0/BnHwDisplayService.h",
"android/frameworks/displayservice/1.0/BpHwDisplayService.h",
"android/frameworks/displayservice/1.0/BsDisplayService.h",
"android/frameworks/displayservice/1.0/IEventCallback.h",
"android/frameworks/displayservice/1.0/IHwEventCallback.h",
"android/frameworks/displayservice/1.0/BnHwEventCallback.h",
"android/frameworks/displayservice/1.0/BpHwEventCallback.h",
"android/frameworks/displayservice/1.0/BsEventCallback.h",
],
}
cc_library {
name: "android.frameworks.displayservice@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.frameworks.displayservice@1.0_genc++"],
generated_headers: ["android.frameworks.displayservice@1.0_genc++_headers"],
export_generated_headers: ["android.frameworks.displayservice@1.0_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
],
}

View file

@ -0,0 +1,202 @@
# This file is autogenerated by hidl-gen. Do not edit manually.
LOCAL_PATH := $(call my-dir)
################################################################################
include $(CLEAR_VARS)
LOCAL_MODULE := android.frameworks.displayservice-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
android.hidl.base-V1.0-java \
#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/Status.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::types.Status
$(GEN): $(LOCAL_PATH)/types.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IDisplayEventReceiver.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IDisplayEventReceiver.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IEventCallback.hal
$(GEN): $(LOCAL_PATH)/IEventCallback.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
$(GEN): $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IDisplayEventReceiver
$(GEN): $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IDisplayService.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IDisplayService.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IDisplayService.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IDisplayService
$(GEN): $(LOCAL_PATH)/IDisplayService.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IEventCallback.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IEventCallback.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IEventCallback.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IEventCallback
$(GEN): $(LOCAL_PATH)/IEventCallback.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_JAVA_LIBRARY)
################################################################################
include $(CLEAR_VARS)
LOCAL_MODULE := android.frameworks.displayservice-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
android.hidl.base-V1.0-java-static \
#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/Status.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::types.Status
$(GEN): $(LOCAL_PATH)/types.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IDisplayEventReceiver.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IDisplayEventReceiver.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IEventCallback.hal
$(GEN): $(LOCAL_PATH)/IEventCallback.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
$(GEN): $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IDisplayEventReceiver
$(GEN): $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IDisplayService.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IDisplayService.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IDisplayService.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): $(LOCAL_PATH)/IDisplayEventReceiver.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IDisplayService
$(GEN): $(LOCAL_PATH)/IDisplayService.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
#
# Build IEventCallback.hal
#
GEN := $(intermediates)/android/frameworks/displayservice/V1_0/IEventCallback.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IEventCallback.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.displayservice@1.0::IEventCallback
$(GEN): $(LOCAL_PATH)/IEventCallback.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_STATIC_JAVA_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.displayservice@1.0;
import IEventCallback;
interface IDisplayEventReceiver {
/**
* Attach callback to start receiving events. Hotplug events are enabled
* by default. Vsync events must be enabled with setVsyncRate.
*
* @return status Must be:
* SUCCESS if callback is initialized correctly.
* BAD_VALUE if callback is nullptr or if this has already been called.
* UNKNOWN if callback cannot be initialized.
*/
init(IEventCallback callback) generates (Status status);
/**
* Must start (or stop) sending callbacks immediately as requested.
*
* @param count Request to be sent a callback for every <count>th event.
* If zero, then only send callbacks when requestNextVsync is
* called. By default, this will be zero. Must be >= 0.
* @return status Must be:
* SUCCESS if rate is set successfully.
* BAD_VALUE if count < 0 or no init.
* UNKNOWN for all other errors.
*/
setVsyncRate(int32_t count) generates (Status status);
/**
* Must have no effect if vsync rate (set with setVsyncRate) is 0.
*
* @return status Must be:
* SUCCESS if request successfully processed.
* BAD_VALUE if no init.
* UNKNOWN for all other errors.
*/
requestNextVsync() generates (Status status);
/**
* Server must drop all references to callback and stop sending events.
* Client must call this method if init was called.
*
* @return status Must be:
* SUCCESS if request successfully processed.
* BAD_VALUE if init has not been called.
* UNKNOWN for all other errors.
*/
close() generates (Status status);
};

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.displayservice@1.0;
import IDisplayEventReceiver;
interface IDisplayService {
/**
* Must create new receiver.
*
* @return receiver Receiver object.
*/
getEventReceiver() generates(IDisplayEventReceiver receiver);
};

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.displayservice@1.0;
interface IEventCallback {
/**
* @param timestamp Nanoseconds since boot.
* @param count Vsync count.
*/
oneway onVsync(uint64_t timestamp, uint32_t count);
/**
* @param timestamp Nanoseconds since boot.
* @param connected Current state of hotplug.
*/
oneway onHotplug(uint64_t timestamp, bool connected);
};

View file

@ -0,0 +1,22 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.displayservice@1.0;
enum Status : uint32_t {
SUCCESS,
BAD_VALUE,
UNKNOWN,
};

View file

@ -0,0 +1,35 @@
//
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
cc_test {
name: "VtsFwkDisplayServiceV1_0TargetTest",
srcs: ["VtsFwkDisplayServiceV1_0TargetTest.cpp"],
shared_libs: [
"android.frameworks.displayservice@1.0",
"libhidlbase",
"libhidltransport",
"liblog",
"libutils",
],
static_libs: ["VtsHalHidlTargetTestBase"],
cflags: [
"-Wall",
"-Werror",
"-O0",
"-g",
]
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "VtsFwkDisplayServiceV1_0TargetTest"
#include <android/frameworks/displayservice/1.0/IDisplayEventReceiver.h>
#include <android/frameworks/displayservice/1.0/IDisplayService.h>
#include <android/frameworks/displayservice/1.0/IEventCallback.h>
#include <log/log.h>
#include <VtsHalHidlTargetTestBase.h>
#include <atomic>
#include <chrono>
#include <cmath>
#include <inttypes.h>
#include <thread>
using ::android::frameworks::displayservice::V1_0::IDisplayEventReceiver;
using ::android::frameworks::displayservice::V1_0::IDisplayService;
using ::android::frameworks::displayservice::V1_0::IEventCallback;
using ::android::frameworks::displayservice::V1_0::Status;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
using namespace ::std::chrono_literals;
#define ASSERT_OK(ret) ASSERT_TRUE((ret).isOk())
#define EXPECT_SUCCESS(retExpr) do { \
Return<Status> retVal = (retExpr); \
ASSERT_OK(retVal); \
EXPECT_EQ(Status::SUCCESS, static_cast<Status>(retVal)); \
} while(false)
#define EXPECT_BAD_VALUE(retExpr) do { \
Return<Status> retVal = (retExpr); \
ASSERT_OK(retVal); \
EXPECT_EQ(Status::BAD_VALUE, static_cast<Status>(retVal)); \
} while(false)
#define MAX_INACCURACY 3
class TestCallback : public IEventCallback {
public:
Return<void> onVsync(uint64_t timestamp, uint32_t count) override {
ALOGE("onVsync: timestamp=%" PRIu64 " count=%d", timestamp, count);
vsyncs++;
return Void();
}
Return<void> onHotplug(uint64_t timestamp, bool connected) override {
ALOGE("onVsync: timestamp=%" PRIu64 " connected=%s", timestamp, connected ? "true" : "false");
hotplugs++;
return Void();
}
std::atomic<int> vsyncs{0};
std::atomic<int> hotplugs{0};
};
class DisplayServiceTest : public ::testing::VtsHalHidlTargetTestBase {
public:
~DisplayServiceTest() {}
virtual void SetUp() override {
sp<IDisplayService> service = ::testing::VtsHalHidlTargetTestBase::getService<IDisplayService>();
ASSERT_NE(service, nullptr);
Return<sp<IDisplayEventReceiver>> ret = service->getEventReceiver();
ASSERT_OK(ret);
receiver = ret;
ASSERT_NE(receiver, nullptr);
cb = new TestCallback();
EXPECT_SUCCESS(receiver->init(cb));
}
virtual void TearDown() override {
EXPECT_SUCCESS(receiver->close());
}
sp<TestCallback> cb;
sp<IDisplayEventReceiver> receiver;
};
/**
* No vsync events should happen unless you explicitly request one.
*/
TEST_F(DisplayServiceTest, TestAttachRequestVsync) {
EXPECT_EQ(0, cb->vsyncs);
EXPECT_SUCCESS(receiver->requestNextVsync());
std::this_thread::sleep_for(100ms); // framerate is not fixed on Android devices
EXPECT_EQ(1, cb->vsyncs);
}
/**
* Vsync rate respects count.
*/
TEST_F(DisplayServiceTest, TestSetVsyncRate) {
ASSERT_EQ(0, cb->vsyncs);
EXPECT_SUCCESS(receiver->setVsyncRate(1));
std::this_thread::sleep_for(250ms);
int at1 = cb->vsyncs;
cb->vsyncs = 0;
EXPECT_SUCCESS(receiver->setVsyncRate(2));
std::this_thread::sleep_for(250ms);
int at2 = cb->vsyncs;
cb->vsyncs = 0;
EXPECT_SUCCESS(receiver->setVsyncRate(4));
std::this_thread::sleep_for(250ms);
int at4 = cb->vsyncs;
EXPECT_NE(0, at1);
EXPECT_NE(0, at2);
EXPECT_NE(0, at4);
EXPECT_LE(std::abs(at1 - 2 * at2), 2 * MAX_INACCURACY);
EXPECT_LE(std::abs(at1 - 4 * at4), 4 * MAX_INACCURACY);
EXPECT_LE(std::abs(at2 - 2 * at4), 2 * MAX_INACCURACY);
ALOGE("Vsync counts: %d %d %d", at1, at2, at4);
}
/**
* Open/close should return proper error results.
*/
TEST_F(DisplayServiceTest, TestOpenClose) {
EXPECT_BAD_VALUE(receiver->init(cb)); // already opened in SetUp
EXPECT_SUCCESS(receiver->close()); // can close what was originally opened
EXPECT_BAD_VALUE(receiver->close()); // can't close again
EXPECT_SUCCESS(receiver->init(cb)); // open so can close again in SetUp
}
/**
* Vsync must be given a value that is >= 0.
*/
TEST_F(DisplayServiceTest, TestVsync) {
EXPECT_SUCCESS(receiver->setVsyncRate(0));
EXPECT_SUCCESS(receiver->setVsyncRate(5));
EXPECT_SUCCESS(receiver->setVsyncRate(0));
EXPECT_BAD_VALUE(receiver->setVsyncRate(-1));
EXPECT_BAD_VALUE(receiver->setVsyncRate(-1000));
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
int status = RUN_ALL_TESTS();
ALOGE("Test status = %d", status);
return status;
}

View file

@ -0,0 +1,62 @@
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "android.frameworks.schedulerservice@1.0_hal",
srcs: [
"ISchedulingPolicyService.hal",
],
}
genrule {
name: "android.frameworks.schedulerservice@1.0_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.frameworks:frameworks/hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.schedulerservice@1.0",
srcs: [
":android.frameworks.schedulerservice@1.0_hal",
],
out: [
"android/frameworks/schedulerservice/1.0/SchedulingPolicyServiceAll.cpp",
],
}
genrule {
name: "android.frameworks.schedulerservice@1.0_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.frameworks:frameworks/hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.schedulerservice@1.0",
srcs: [
":android.frameworks.schedulerservice@1.0_hal",
],
out: [
"android/frameworks/schedulerservice/1.0/ISchedulingPolicyService.h",
"android/frameworks/schedulerservice/1.0/IHwSchedulingPolicyService.h",
"android/frameworks/schedulerservice/1.0/BnHwSchedulingPolicyService.h",
"android/frameworks/schedulerservice/1.0/BpHwSchedulingPolicyService.h",
"android/frameworks/schedulerservice/1.0/BsSchedulingPolicyService.h",
],
}
cc_library {
name: "android.frameworks.schedulerservice@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.frameworks.schedulerservice@1.0_genc++"],
generated_headers: ["android.frameworks.schedulerservice@1.0_genc++_headers"],
export_generated_headers: ["android.frameworks.schedulerservice@1.0_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
],
}

View file

@ -0,0 +1,76 @@
# This file is autogenerated by hidl-gen. Do not edit manually.
LOCAL_PATH := $(call my-dir)
################################################################################
include $(CLEAR_VARS)
LOCAL_MODULE := android.frameworks.schedulerservice-V1.0-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_JAVA_LIBRARIES := \
android.hidl.base-V1.0-java \
#
# Build ISchedulingPolicyService.hal
#
GEN := $(intermediates)/android/frameworks/schedulerservice/V1_0/ISchedulingPolicyService.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISchedulingPolicyService.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.schedulerservice@1.0::ISchedulingPolicyService
$(GEN): $(LOCAL_PATH)/ISchedulingPolicyService.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_JAVA_LIBRARY)
################################################################################
include $(CLEAR_VARS)
LOCAL_MODULE := android.frameworks.schedulerservice-V1.0-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
intermediates := $(call local-generated-sources-dir, COMMON)
HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
LOCAL_STATIC_JAVA_LIBRARIES := \
android.hidl.base-V1.0-java-static \
#
# Build ISchedulingPolicyService.hal
#
GEN := $(intermediates)/android/frameworks/schedulerservice/V1_0/ISchedulingPolicyService.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISchedulingPolicyService.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-Ljava \
-randroid.frameworks:frameworks/hardware/interfaces \
-randroid.hidl:system/libhidl/transport \
android.frameworks.schedulerservice@1.0::ISchedulingPolicyService
$(GEN): $(LOCAL_PATH)/ISchedulingPolicyService.hal
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_STATIC_JAVA_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.schedulerservice@1.0;
interface ISchedulingPolicyService {
enum Priority : int32_t {
MIN = 1,
MAX = 99,
};
/**
* Request real-time priority for a specific thread in a process.
*
* @param pid Process ID.
* @param tid Thread ID.
* @param priority Value within [Priority:MIN, Priority:MAX]
*
* @return success whether or not priority was successfully set
*/
requestPriority(int32_t pid, int32_t tid, int32_t priority)
generates (bool success);
/**
* Must return 0 if no priority is allowed.
*
* @return priority Max priority that can be set with
* requestPriority.
*/
getMaxAllowedPriority() generates (int32_t priority);
};

View file

@ -0,0 +1,89 @@
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "android.frameworks.sensorservice@1.0_hal",
srcs: [
"types.hal",
"IDirectReportChannel.hal",
"IEventQueue.hal",
"IEventQueueCallback.hal",
"ISensorManager.hal",
],
}
genrule {
name: "android.frameworks.sensorservice@1.0_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.frameworks:frameworks/hardware/interfaces -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.sensorservice@1.0",
srcs: [
":android.frameworks.sensorservice@1.0_hal",
],
out: [
"android/frameworks/sensorservice/1.0/types.cpp",
"android/frameworks/sensorservice/1.0/DirectReportChannelAll.cpp",
"android/frameworks/sensorservice/1.0/EventQueueAll.cpp",
"android/frameworks/sensorservice/1.0/EventQueueCallbackAll.cpp",
"android/frameworks/sensorservice/1.0/SensorManagerAll.cpp",
],
}
genrule {
name: "android.frameworks.sensorservice@1.0_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.frameworks:frameworks/hardware/interfaces -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.sensorservice@1.0",
srcs: [
":android.frameworks.sensorservice@1.0_hal",
],
out: [
"android/frameworks/sensorservice/1.0/types.h",
"android/frameworks/sensorservice/1.0/hwtypes.h",
"android/frameworks/sensorservice/1.0/IDirectReportChannel.h",
"android/frameworks/sensorservice/1.0/IHwDirectReportChannel.h",
"android/frameworks/sensorservice/1.0/BnHwDirectReportChannel.h",
"android/frameworks/sensorservice/1.0/BpHwDirectReportChannel.h",
"android/frameworks/sensorservice/1.0/BsDirectReportChannel.h",
"android/frameworks/sensorservice/1.0/IEventQueue.h",
"android/frameworks/sensorservice/1.0/IHwEventQueue.h",
"android/frameworks/sensorservice/1.0/BnHwEventQueue.h",
"android/frameworks/sensorservice/1.0/BpHwEventQueue.h",
"android/frameworks/sensorservice/1.0/BsEventQueue.h",
"android/frameworks/sensorservice/1.0/IEventQueueCallback.h",
"android/frameworks/sensorservice/1.0/IHwEventQueueCallback.h",
"android/frameworks/sensorservice/1.0/BnHwEventQueueCallback.h",
"android/frameworks/sensorservice/1.0/BpHwEventQueueCallback.h",
"android/frameworks/sensorservice/1.0/BsEventQueueCallback.h",
"android/frameworks/sensorservice/1.0/ISensorManager.h",
"android/frameworks/sensorservice/1.0/IHwSensorManager.h",
"android/frameworks/sensorservice/1.0/BnHwSensorManager.h",
"android/frameworks/sensorservice/1.0/BpHwSensorManager.h",
"android/frameworks/sensorservice/1.0/BsSensorManager.h",
],
}
cc_library {
name: "android.frameworks.sensorservice@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.frameworks.sensorservice@1.0_genc++"],
generated_headers: ["android.frameworks.sensorservice@1.0_genc++_headers"],
export_generated_headers: ["android.frameworks.sensorservice@1.0_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
"android.hardware.sensors@1.0",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
"android.hardware.sensors@1.0",
],
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.sensorservice@1.0;
import android.hardware.sensors@1.0::RateLevel;
/**
* The interface represents a direct channel created by
* ISensorManager.createSharedMemoryDirectChannel() and
* ISensorMangaer.createHardwareBufferDirectChannel().
*/
interface IDirectReportChannel {
/**
* Configure direct report on channel
*
* Configure sensor direct report on a direct channel: set rate to value
* other than STOP so that sensor event can be directly written into the
* shared memory region used for creating the channel; set rate to STOP will
* stop the sensor direct report.
*
* To stop all active sensor direct report configured to a channel, set
* sensorHandle to -1 and rate to STOP.
*
* @param sensorHandle handle of the sensor to operate on. If it is -1
* and rate is STOP, the call must stop of all active
* sensor direct report.
* @param rate rate level value to set on the specified sensor.
*
* @return result OK on success;
* BAD_VALUE if parameter is invalid (for example,
* rate level is not supported by sensor, etc);
* INVALID_OPERATION if functionality is not supported.
* @return token the token used to distinguish sensor events from
* multiple different sensors of the same type in a
* single direct channel, or 0 if: (1) no such token
* may be returned or (2) error (in which case result
* must be value other than OK).
*/
configure(int32_t sensorHandle, RateLevel rate)
generates (int32_t token, Result result);
};

View file

@ -0,0 +1,53 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.sensorservice@1.0;
/**
* An IEventQueue is an interface to manage an event queue created by
* ISensorManager.
*/
interface IEventQueue {
/**
* Enable the selected sensor with a specified sampling period and
* max batch report latency. If enableSensor is called multiple times on the
* same sensor, the previous calls must be overridden by the last call.
*
* @param sensorHandle the sensor to enable. Must be a sensor acquired from
* the ISensorManager that creates this IEventQueue.
* @param samplingPeriodUs
* sampling period in microseconds.
* @param maxBatchReportLatencyUs
* max batch report latency in microseconds.
* @return result OK if successful, or
* PERMISSION_DENIED, BAD_VALUE, INVALID_OPERATION,
* NO_INIT for errors.
*/
enableSensor(int32_t sensorHandle,
int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs)
generates (Result result);
/**
* Disable the selected sensor.
*
* @param sensorHandle the sensor to disable. Must be a sensor acquired from
* the ISensorManager that creates this IEventQueue.
* @return result OK if successful,
* BAD_VALUE or NO_INIT for errors.
*/
disableSensor(int32_t sensorHandle) generates (Result result);
};

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.sensorservice@1.0;
import android.hardware.sensors@1.0::Event;
/**
* An IEventQueueCallback describes the callback that is called upon
* any events.
*/
interface IEventQueueCallback {
/**
* When any event is obtained from the sensor, this function must be called
* with the event data.
*
* Implementation of this function must finish in short time predictably.
* It must never block or run for extended period of time. It must offload
* heavy computation to a separate thread.
*
* @param event the event data.
*/
oneway onEvent(Event event);
};

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.sensorservice@1.0;
import IDirectReportChannel;
import IEventQueue;
import IEventQueueCallback;
import android.hardware.sensors@1.0::SensorInfo;
import android.hardware.sensors@1.0::SensorType;
/**
* ISensorManager is an interface to manage sensors
*
* This file provides a set of functions that uses
* ISensorManager to access and list hardware sensors.
*/
interface ISensorManager {
/**
* Get the list of available sensors.
*
* @return list the list of available sensors, or empty on failure
* @return result OK on success or UNKNOWN_ERROR on failure
*/
getSensorList() generates (vec<SensorInfo> list, Result result);
/**
* Get the default sensor of the specified type.
*
* @return sensor the default sensor for the given type, or undetermined
* value on failure.
* @return result OK on success or
NOT_EXIST if no sensor of that type exists.
*/
getDefaultSensor(SensorType type)
generates (SensorInfo sensor, Result result);
/**
* Create direct channel based on shared memory
*
* Create a direct channel of DIRECT_CHANNEL_ASHMEM type to be used
* for configuring sensor direct report.
*
* The memory layout looks as follows. These offsets can be found in
* android.hardware.sensors@1.0::SensorsEventFormatOffset.
* offset type name
* -----------------------------------
* 0x0000 int32_t size (SensorsEventFormatOffset::TOTAL_LENGTH)
* 0x0004 int32_t sensor report token
* 0x0008 int32_t type (see android.hardware.sensors@1.0::SensorType)
* 0x000C uint32_t atomic counter
* 0x0010 int64_t timestamp (see android.hardware.sensors@1.0::Event)
* 0x0018 float[16]/ data
* int64_t[8]
* 0x0058 int32_t[4] reserved (set to zero)
*
* @param mem the shared memory to use, must be ashmem.
* @param size the intended size to be used. The following must be true:
* SensorsEventFormatOffset::TOTAL_LENGTH <= size <= mem.size
*
* @return chan The created channel, or NULL if failure.
* @return result OK if successful;
* BAD_VALUE if size > mem.size();
* BAD_VALUE if size < TOTAL_LENGTH;
* NO_MEMORY, NO_INIT, BAD_VALUE for underlying errors;
* UNKNOWN_ERROR if the underlying error is not recognized;
* UNKNOWN_ERROR if the underlying call returns channelId = 0
*/
createAshmemDirectChannel(memory mem, uint64_t size)
generates (IDirectReportChannel chan, Result result);
/**
* Create direct channel based on hardware buffer
*
* Create a direct channel of DIRECT_CHANNEL_GRALLOC type to be used
* for configuring sensor direct report.
*
* @param buffer file descriptor describing the gralloc buffer.
* @param size the intended size to be used, must be less than or equal
* to the size of the buffer.
*
* @return chan The created channel, or NULL if failure.
* @return result OK if successful;
* NO_MEMORY, NO_INIT, BAD_VALUE for underlying errors;
* UNKNOWN_ERROR if the underlying error is not recognized;
* UNKNOWN_ERROR if the underlying call returns channelId = 0
*/
createGrallocDirectChannel(handle buffer, uint64_t size)
generates (IDirectReportChannel chan, Result result);
/**
* Create a sensor event queue.
*
* Create a sensor event queue with an IEventQueueCallback object.
* Subsequently, one can enable sensors on the event queue so that sensor
* events are passed via the specified callback.
*
* @param callback the callback to call on events. Must not be null.
* @return queue the event queue created. null on failure.
* @return result OK if successful, BAD_VALUE if callback is null,
* or other Result values for any underlying errors.
*/
createEventQueue(IEventQueueCallback callback)
generates (IEventQueue queue, Result result);
};

View file

@ -0,0 +1,140 @@
==== Summary ====
android.frameworks.sensorservice@1.0 is a package that mimics the sensors API in
NDK (sensor.h). It includes a subset of these APIs and introduces a few
adaptations.
=== Design Details ===
- ISensorManager
ISensorMangaer includes member functions that adapts the ASensorManager_*
series in NDK. An instance of ISensorManager must be able to
- retrieve sensors
- create direct report channel
- create event queue
- IDirectReportChannel
IDirectReportChannel corresponds to a channel ID, an integer obtained in
ASensorManager_createSharedMemoryDirectChannel and
ASensorManager_createHardwareBufferDirectChannel. An instance of
IDirectReportChannel must also destroy it against the sensor manager. An
IDirectReportChannel must be able to configure itself (an adaptation to
ASensorManager_configureDirectReport). The implementation must also call
ASensorManager_destroyEventQueue on destruction of IDirectReportChannel.
Usage typically looks like this (transaction errors are not handled):
sp<ISensorManager> manager = ISensorManager::getService();
int32_t sensorHandle;
manager->getDefaultSensor(SensorType::GYROSCOPE,
[&sensorHandle] (const auto &info) {
sensorHandle = info.sensorHandle;
});
hidl_memory mem;
const uint64_t size = 4096;
::android::hidl::memory::V1_0::IAllocator::getService()->allocate(size,
[&](auto, const auto &m) { mem = m; });
if (!mem.handle()) {
/* error handling */
}
sp<IDirectChannel> chan;
Result res;
manager->createAshmemDirectChannel(mem, size,
[&chan, &res] (const auto &c, auto r) {
chan = c; res = r;
});
if (res != Result::OK) { /* error handling */ }
chan->configure(sensorHandle, RateLevel::FAST, [&](auto token, auto result) {
if (result != Result::OK) {
/* error handling */
}
});
/* obtain sensor events from shared memory */
chan->configure(sensorHandle, RateLevel::STOP, [&](auto token, auto result) {
if (result != Result::OK) {
/* error handling */
}
});
/*
* Free the channel.
* kernel calls decStrong() on server side implementation of IDirectChannel,
* hence resources are freed as well.
*/
chan = nullptr;
- IEventQueue, IEventQueueCallback
IEventQueue includes member functions that adapts some of the
ASensorEventQueue_* seeries in NDK. An instance of IEventQueue must be able to
- enable selected sensors (adapts ASensorEventQueue_registerSensor)
- disable selected sensors (adapts ASensorEventQueue_disableSensor)
The implementation must free all resources related to this IEventQueue instance
and call ASensorManager_destroyEventQueue on destruction of IEventQueue.
Unlike NDK ASensorEventQueue_hasEvents and ASensorEventQueue_getEvents, which
implies a poll model for sensor events, IEventQueue uses a push model by using
callbacks. When creating an event queue, client must provide an instance of
IEventQueueCallback. The implementation of IEventQueue must either use a global
looper or create a new looper to call on ASensorManager_createEventQueue. The
server implementation must use this looper to constantly poll for events, then
invoke the callback when any event is fired.
IEventQueueCallback.onEvent is designed to be oneway, because the server should
not wait for the client to finish handling the event. The callback
should finish in a predictably short time, and should not block or run for an
extended period of time. The callbacks can be invoked in a very high frequency;
a long running callback means delay in handling of subsequent events and filling
up the (kernel binder buffer) memory space of the client process, eventually the
server sees a transaction error when issuing the callback. It is up to the
client to be configured single-threaded or multi-threaded to handle these
callbacks.
- Single-threaded clients receive events in the correct order in the same
thread.
- Multi-threaded clients receive events in the correct order but in
different threads; it is the clients' responsibility to deal with
concurrency issues and handle events in the expected order to avoid race
conditions.
Usage typically looks like this (transaction errors are not handled):
struct Callback : IEventQueueCallback {
Return<void> onEvent(const Event &e) {
/* handle sensor event e */
}
};
sp<ISensorManager> manager = ISensorManager::getService();
int32_t sensorHandle;
manager->getDefaultSensor(SensorType::GYROSCOPE,
[&sensorHandle] (const auto &info) {
sensorHandle = info.sensorHandle;
});
sp<IEventQueue> queue;
Result res;
manager->createEventQueue(new Callback(),
[&queue, &res] (const auto &q, auto r) {
queue = q; res = r;
});
/* Server side implementation of IEventQueue holds a strong reference to
* the callback. */
if (res != Result::OK) { /* error handling */ }
if (q->enableSensor(sensorHandle,
20000 /* sample period */, 0 /* latency */) != Result::OK) {
/* error handling */
}
/* start receiving events via onEvent */
if (q->disableSensor(sensorHandle) != Result::OK) {
/* error handling */
}
/*
* Free the event queue.
* kernel calls decStrong() on server side implementation of IEventQueue,
* hence resources (including the callback) are freed as well.
*/
queue = nullptr;

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.sensorservice@1.0;
enum Result : int32_t {
OK = 0,
NOT_EXIST,
NO_MEMORY,
NO_INIT,
PERMISSION_DENIED,
BAD_VALUE,
INVALID_OPERATION,
UNKNOWN_ERROR
};

View file

@ -0,0 +1,37 @@
//
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
cc_test {
name: "VtsHalSensorManagerV1_0TargetTest",
defaults: ["hidl_defaults"],
srcs: ["VtsHalSensorManagerV1_0TargetTest.cpp"],
shared_libs: [
"libbase",
"libcutils",
"libhidlbase",
"libutils",
"android.hidl.allocator@1.0",
"android.hardware.sensors@1.0",
"android.frameworks.sensorservice@1.0",
],
static_libs: [
"android.hardware.sensors@1.0-convert",
],
cflags: [
"-O0",
"-g",
],
}

View file

@ -0,0 +1,265 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "sensor_manager_hidl_hal_test"
#include <android-base/logging.h>
#include <sys/mman.h>
#include <chrono>
#include <thread>
#include <android/sensor.h>
#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
#include <android/frameworks/sensorservice/1.0/types.h>
#include <android/hardware/sensors/1.0/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <gtest/gtest.h>
#include <sensors/convert.h>
using ::android::frameworks::sensorservice::V1_0::ISensorManager;
using ::android::frameworks::sensorservice::V1_0::Result;
using ::android::hardware::sensors::V1_0::Event;
using ::android::hardware::sensors::V1_0::RateLevel;
using ::android::hardware::sensors::V1_0::SensorFlagBits;
using ::android::hardware::sensors::V1_0::SensorFlagShift;
using ::android::hardware::sensors::V1_0::SensorType;
using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_memory;
using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::sp;
template <typename T>
static inline ::testing::AssertionResult isOk(const Return<T> &ret) {
return (ret.isOk()
? ::testing::AssertionSuccess()
: ::testing::AssertionFailure()) << ret.description();
}
template <>
__attribute__((__unused__))
inline ::testing::AssertionResult isOk(const Return<Result> &ret) {
return ((ret.isOk() && ret == Result::OK)
? ::testing::AssertionSuccess()
: ::testing::AssertionFailure())
<< ret.description() << ", "
<< (ret.isOk() ? toString(static_cast<Result>(ret)) : "");
}
static inline ::testing::AssertionResult isOk(Result result) {
using ::android::frameworks::sensorservice::V1_0::toString;
return (result == Result::OK
? ::testing::AssertionSuccess()
: ::testing::AssertionFailure()) << toString(result);
}
template<typename I, typename F>
static ::testing::AssertionResult isIncreasing(I begin, I end, F getField) {
typename std::iterator_traits<I>::pointer lastValue = nullptr;
I iter;
size_t pos;
for (iter = begin, pos = 0; iter != end; ++iter, ++pos) {
if (iter == begin) {
lastValue = &(*iter);
continue;
}
if (getField(*iter) < getField(*lastValue)) {
return ::testing::AssertionFailure() << "Not an increasing sequence, pos = "
<< pos << ", " << getField(*iter) << " < " << getField(*lastValue);
}
}
return ::testing::AssertionSuccess();
}
#define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
#define ASSERT_OK(__ret__) ASSERT_TRUE(isOk(__ret__))
// The main test class for sensorservice HIDL HAL.
class SensorManagerTest : public ::testing::Test {
public:
virtual void SetUp() override {
manager_ = ISensorManager::getService();
ASSERT_NE(manager_, nullptr);
ashmem_ = IAllocator::getService("ashmem");
ASSERT_NE(ashmem_, nullptr);
}
virtual void TearDown() override {}
sp<ISensorManager> manager_;
sp<IAllocator> ashmem_;
};
// A class for test environment setup (kept since this file is a template).
class SensorManagerHidlEnvironment : public ::testing::Environment {
public:
virtual void SetUp() {}
virtual void TearDown() {}
};
using map_region = std::unique_ptr<void, std::function<void(void*)>>;
map_region map(const hidl_memory &mem) {
if (mem.handle() == nullptr || mem.handle()->numFds != 1) {
return nullptr;
}
size_t size = mem.size();
void *buf = mmap(nullptr, size, PROT_READ, MAP_SHARED, mem.handle()->data[0], 0);
return map_region{buf, [size](void *localBuf) {
munmap(localBuf, size);
}};
}
/*
* Ping! make sure the service is alive.
*/
TEST_F(SensorManagerTest, Ping) {
EXPECT_OK(manager_->ping());
}
TEST_F(SensorManagerTest, List) {
ASSERT_OK(manager_->getSensorList([] (__unused const auto &list, auto result) {
using ::android::hardware::sensors::V1_0::toString;
ASSERT_OK(result);
// Do something to the list of sensors.
}));
}
TEST_F(SensorManagerTest, Ashmem) {
auto testOne = [this](uint64_t memSize, uint64_t intendedSize,
ISensorManager::createAshmemDirectChannel_cb callback) {
ASSERT_OK(ashmem_->allocate(memSize, [&](bool success, const auto &mem) {
ASSERT_TRUE(success);
ASSERT_NE(mem.handle(), nullptr);
ASSERT_OK(manager_->createAshmemDirectChannel(mem, intendedSize, callback));
}));
};
testOne(16, 16, [](const auto &chan, Result result) {
EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when memory size is too small";
EXPECT_EQ(chan, nullptr);
});
testOne(1024, 1024, [](const auto &chan, Result result) {
EXPECT_OK(result);
EXPECT_NE(chan, nullptr);
});
testOne(1024, 2048, [](const auto &chan, Result result) {
EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when intended size is too big";
EXPECT_EQ(chan, nullptr);
});
testOne(1024, 16, [](const auto &chan, Result result) {
EXPECT_EQ(result, Result::BAD_VALUE) << "unexpected result when intended size is too small";
EXPECT_EQ(chan, nullptr);
});
}
static std::vector<Event> parseEvents(uint8_t *buf, size_t memSize) {
using O = SensorsEventFormatOffset;
using ::android::hardware::sensors::V1_0::implementation::convertFromSensorEvent;
size_t offset = 0;
int64_t lastCounter = -1;
std::vector<Event> events;
Event event;
while(offset + (size_t)O::TOTAL_LENGTH <= memSize) {
uint8_t *start = buf + offset;
int64_t atomicCounter = *reinterpret_cast<uint32_t *>(start + (size_t)O::ATOMIC_COUNTER);
if (atomicCounter <= lastCounter) {
break;
}
int32_t size = *reinterpret_cast<int32_t *>(start + (size_t)O::SIZE_FIELD);
if (size != (size_t)O::TOTAL_LENGTH) {
// unknown error, events parsed may be wrong, remove all
events.clear();
break;
}
convertFromSensorEvent(*reinterpret_cast<const sensors_event_t *>(start), &event);
events.push_back(event);
lastCounter = atomicCounter;
offset += (size_t)O::TOTAL_LENGTH;
}
return events;
}
TEST_F(SensorManagerTest, Accelerometer) {
using std::literals::chrono_literals::operator""ms;
using ::android::hardware::sensors::V1_0::implementation::convertFromRateLevel;
Result getSensorResult;
int32_t handle;
ASSERT_OK(manager_->getDefaultSensor(SensorType::ACCELEROMETER, [&] (const auto &info, auto result) {
getSensorResult = result;
handle = info.sensorHandle;
if (result == Result::OK) {
ASSERT_TRUE(info.flags & SensorFlagBits::DIRECT_CHANNEL_ASHMEM);
int maxLevel = (info.flags & SensorFlagBits::MASK_DIRECT_REPORT)
>> (int)SensorFlagShift::DIRECT_REPORT;
ASSERT_TRUE(maxLevel >= convertFromRateLevel(RateLevel::FAST))
<< "Accelerometer does not support fast report rate, test cannot proceed.";
}
}));
if (getSensorResult == Result::NOT_EXIST) {
LOG(WARNING) << "Cannot find accelerometer, skipped SensorManagerTest.Accelerometer";
return;
}
ASSERT_OK(getSensorResult);
const size_t memSize = (size_t)SensorsEventFormatOffset::TOTAL_LENGTH * 300;
ASSERT_OK(ashmem_->allocate(memSize, [&] (bool success, const auto &mem) {
ASSERT_TRUE(success);
map_region buf = map(mem);
ASSERT_NE(buf, nullptr);
ASSERT_OK(manager_->createAshmemDirectChannel(mem, memSize, [&](const auto &chan, Result result) {
ASSERT_OK(result);
ASSERT_NE(chan, nullptr);
int32_t returnedToken;
ASSERT_OK(chan->configure(handle, RateLevel::FAST, [&](auto token, auto res) {
ASSERT_OK(res);
ASSERT_GT(token, 0);
returnedToken = token;
})); // ~200Hz
std::this_thread::sleep_for(500ms);
ASSERT_OK(chan->configure(handle, RateLevel::STOP, [](auto token, auto res) {
ASSERT_OK(res);
ASSERT_EQ(token, 0);
}));
auto events = parseEvents(static_cast<uint8_t *>(buf.get()), memSize);
EXPECT_TRUE(isIncreasing(events.begin(), events.end(), [](const auto &event) {
return event.timestamp;
})) << "timestamp is not monotonically increasing";
for (const auto &event : events) {
EXPECT_EQ(returnedToken, event.sensorHandle)
<< "configure token and sensor handle don't match.";
}
}));
}));
}
int main(int argc, char** argv) {
::testing::AddGlobalTestEnvironment(new SensorManagerHidlEnvironment);
::testing::InitGoogleTest(&argc, argv);
int status = RUN_ALL_TESTS();
LOG(INFO) << "Test result = " << status;
return status;
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ALooper.h"
#include "ASensorEventQueue.h"
#define LOG_TAG "libsensorndkbridge"
#include <android/looper.h>
#include <android-base/logging.h>
using android::Mutex;
ALooper::ALooper()
: mAwoken(false) {
}
void ALooper::signalSensorEvents(ASensorEventQueue *queue) {
Mutex::Autolock autoLock(mLock);
mReadyQueues.insert(queue);
mCondition.signal();
}
void ALooper::wake() {
Mutex::Autolock autoLock(mLock);
mAwoken = true;
mCondition.signal();
}
int ALooper::pollOnce(
int timeoutMillis, int *outFd, int *outEvents, void **outData) {
if (outFd) { *outFd = 0; }
if (outEvents) { *outEvents = 0; }
if (outData) { *outData = NULL; }
int64_t waitUntilNs;
if (timeoutMillis < 0) {
waitUntilNs = -1;
} else {
waitUntilNs =
systemTime(SYSTEM_TIME_MONOTONIC) + timeoutMillis * 1000000ll;
}
Mutex::Autolock autoLock(mLock);
int64_t nowNs;
while ((timeoutMillis < 0
|| (nowNs = systemTime(SYSTEM_TIME_MONOTONIC)) < waitUntilNs)
&& mReadyQueues.empty()
&& !mAwoken) {
if (timeoutMillis < 0) {
mCondition.wait(mLock);
} else {
mCondition.waitRelative(mLock, waitUntilNs - nowNs);
}
}
int result = ALOOPER_POLL_TIMEOUT;
if (!mReadyQueues.empty()) {
result = ALOOPER_POLL_CALLBACK;
for (auto queue : mReadyQueues) {
queue->dispatchCallback();
}
mReadyQueues.clear();
} else if (mAwoken) {
result = ALOOPER_POLL_WAKE;
mAwoken = false;
}
LOG(VERBOSE) << "pollOnce returning " << result;
return result;
}
void ALooper::invalidateSensorQueue(ASensorEventQueue *queue) {
Mutex::Autolock autoLock(mLock);
mReadyQueues.erase(queue);
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef A_LOOPER_H_
#define A_LOOPER_H_
#include <android-base/macros.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <set>
struct ASensorEventQueue;
struct ALooper {
ALooper();
void signalSensorEvents(ASensorEventQueue *queue);
void wake();
int pollOnce(int timeoutMillis, int *outFd, int *outEvents, void **outData);
void invalidateSensorQueue(ASensorEventQueue *queue);
private:
android::Mutex mLock;
android::Condition mCondition;
std::set<ASensorEventQueue *> mReadyQueues;
bool mAwoken;
DISALLOW_COPY_AND_ASSIGN(ALooper);
};
#endif // A_LOOPER_H_

View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ASensorEventQueue.h"
#include "ALooper.h"
#define LOG_TAG "libsensorndkbridge"
#include <android-base/logging.h>
using android::sp;
using android::frameworks::sensorservice::V1_0::Result;
using android::hardware::sensors::V1_0::SensorInfo;
using android::OK;
using android::BAD_VALUE;
using android::Mutex;
using android::hardware::Return;
ASensorEventQueue::ASensorEventQueue(
ALooper *looper, int ident, ALooper_callbackFunc callback, void *data)
: mLooper(looper),
mIdent(ident),
mCallback(callback),
mData(data) {
}
void ASensorEventQueue::setImpl(const sp<IEventQueue> &queueImpl) {
mQueueImpl = queueImpl;
}
int ASensorEventQueue::registerSensor(
ASensorRef sensor,
int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs) {
Return<Result> ret = mQueueImpl->enableSensor(
reinterpret_cast<const SensorInfo *>(sensor)->sensorHandle,
samplingPeriodUs,
maxBatchReportLatencyUs);
if (!ret.isOk()) {
return BAD_VALUE;
}
return OK;
}
int ASensorEventQueue::enableSensor(ASensorRef sensor) {
static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
return registerSensor(
sensor, SENSOR_DELAY_NORMAL, 0 /* maxBatchReportLatencyUs */);
}
int ASensorEventQueue::setEventRate(
ASensorRef sensor, int32_t samplingPeriodUs) {
// Technically this is not supposed to enable the sensor but using this
// API without enabling the sensor first is a no-op, so...
return registerSensor(
sensor, samplingPeriodUs, 0 /* maxBatchReportLatencyUs */);
}
int ASensorEventQueue::disableSensor(ASensorRef sensor) {
Return<Result> ret = mQueueImpl->disableSensor(
reinterpret_cast<const SensorInfo *>(sensor)->sensorHandle);
return ret.isOk() ? OK : BAD_VALUE;
}
ssize_t ASensorEventQueue::getEvents(ASensorEvent *events, size_t count) {
// XXX Should this block if there aren't any events in the queue?
Mutex::Autolock autoLock(mLock);
static_assert(
sizeof(ASensorEvent) == sizeof(sensors_event_t), "mismatched size");
size_t copy = std::min(count, mQueue.size());
for (size_t i = 0; i < copy; ++i) {
reinterpret_cast<sensors_event_t *>(events)[i] = mQueue[i];
}
mQueue.erase(mQueue.begin(), mQueue.begin() + copy);
LOG(VERBOSE) << "ASensorEventQueue::getEvents() returned " << copy << " events.";
return copy;
}
int ASensorEventQueue::hasEvents() const {
return mQueue.empty();
}
Return<void> ASensorEventQueue::onEvent(const Event &event) {
LOG(VERBOSE) << "ASensorEventQueue::onEvent";
{
Mutex::Autolock autoLock(mLock);
mQueue.emplace_back();
sensors_event_t *sensorEvent = &mQueue[mQueue.size() - 1];
android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
event, sensorEvent);
}
mLooper->signalSensorEvents(this);
return android::hardware::Void();
}
void ASensorEventQueue::dispatchCallback() {
if (mCallback != NULL) {
int res = (*mCallback)(-1 /* fd */, ALOOPER_EVENT_INPUT, mData);
if (res == 0) {
mCallback = NULL;
mData = NULL;
}
}
}
void ASensorEventQueue::invalidate() {
mLooper->invalidateSensorQueue(this);
setImpl(nullptr);
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef A_SENSOR_EVENT_QUEUE_H_
#define A_SENSOR_EVENT_QUEUE_H_
#include <android/frameworks/sensorservice/1.0/IEventQueue.h>
#include <android/frameworks/sensorservice/1.0/IEventQueueCallback.h>
#include <android/looper.h>
#include <android/sensor.h>
#include <android-base/macros.h>
#include <sensors/convert.h>
#include <utils/Mutex.h>
struct ALooper;
struct ASensorEventQueue
: public android::frameworks::sensorservice::V1_0::IEventQueueCallback {
using Event = android::hardware::sensors::V1_0::Event;
using IEventQueue = android::frameworks::sensorservice::V1_0::IEventQueue;
ASensorEventQueue(
ALooper *looper,
int ident,
ALooper_callbackFunc callback,
void *data);
android::hardware::Return<void> onEvent(const Event &event) override;
void setImpl(const android::sp<IEventQueue> &queueImpl);
int registerSensor(
ASensorRef sensor,
int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs);
int enableSensor(ASensorRef sensor);
int disableSensor(ASensorRef sensor);
int setEventRate(ASensorRef sensor, int32_t samplingPeriodUs);
ssize_t getEvents(ASensorEvent *events, size_t count);
int hasEvents() const;
void dispatchCallback();
void invalidate();
private:
ALooper *mLooper;
int mIdent;
ALooper_callbackFunc mCallback;
void *mData;
android::sp<IEventQueue> mQueueImpl;
android::Mutex mLock;
std::vector<sensors_event_t> mQueue;
DISALLOW_COPY_AND_ASSIGN(ASensorEventQueue);
};
#endif // A_SENSOR_EVENT_QUEUE_H_

View file

@ -0,0 +1,447 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ALooper.h"
#include "ASensorEventQueue.h"
#include "ASensorManager.h"
#define LOG_TAG "libsensorndkbridge"
#include <android-base/logging.h>
#include <android/looper.h>
#include <hidl/HidlTransportSupport.h>
#include <sensors/convert.h>
using android::hardware::sensors::V1_0::SensorInfo;
using android::frameworks::sensorservice::V1_0::IEventQueue;
using android::frameworks::sensorservice::V1_0::ISensorManager;
using android::frameworks::sensorservice::V1_0::Result;
using android::hardware::sensors::V1_0::SensorType;
using android::sp;
using android::wp;
using android::Mutex;
using android::status_t;
using android::OK;
using android::NO_INIT;
using android::BAD_VALUE;
using android::hardware::hidl_vec;
using android::hardware::Return;
static Mutex gLock;
// static
ASensorManager *ASensorManager::sInstance = NULL;
// static
ASensorManager *ASensorManager::getInstance() {
Mutex::Autolock autoLock(gLock);
if (sInstance == NULL) {
sInstance = new ASensorManager;
if (sInstance->initCheck() != OK) {
delete sInstance;
sInstance = NULL;
}
}
return sInstance;
}
void ASensorManager::SensorDeathRecipient::serviceDied(
uint64_t, const wp<::android::hidl::base::V1_0::IBase>&) {
LOG(ERROR) << "Sensor service died. Cleanup sensor manager instance!";
Mutex::Autolock autoLock(gLock);
delete sInstance;
sInstance = NULL;
}
ASensorManager::ASensorManager()
: mInitCheck(NO_INIT) {
mManager = ISensorManager::getService();
if (mManager != NULL) {
mDeathRecipient = new SensorDeathRecipient();
Return<bool> linked = mManager->linkToDeath(mDeathRecipient, /*cookie*/ 0);
if (!linked.isOk()) {
LOG(ERROR) << "Transaction error in linking to sensor service death: " <<
linked.description().c_str();
} else if (!linked) {
LOG(WARNING) << "Unable to link to sensor service death notifications";
} else {
LOG(DEBUG) << "Link to sensor service death notification successful";
mInitCheck = OK;
}
}
}
status_t ASensorManager::initCheck() const {
return mInitCheck;
}
int ASensorManager::getSensorList(ASensorList *out) {
LOG(VERBOSE) << "ASensorManager::getSensorList";
Mutex::Autolock autoLock(mLock);
if (mSensorList == NULL) {
Return<void> ret =
mManager->getSensorList([&](const auto &list, auto result) {
if (result != Result::OK) {
return;
}
mSensors = list;
});
(void)ret.isOk();
mSensorList.reset(new ASensorRef[mSensors.size()]);
for (size_t i = 0; i < mSensors.size(); ++i) {
mSensorList.get()[i] =
reinterpret_cast<ASensorRef>(&mSensors[i]);
}
}
if (out) {
*out = reinterpret_cast<ASensorList>(mSensorList.get());
}
return mSensors.size();
}
ASensorRef ASensorManager::getDefaultSensor(int type) {
(void)getSensorList(NULL /* list */);
ASensorRef defaultSensor = NULL;
Return<void> ret = mManager->getDefaultSensor(
static_cast<SensorType>(type),
[&](const auto &sensor, auto result) {
if (result != Result::OK) {
return;
}
for (size_t i = 0; i < mSensors.size(); ++i) {
if (sensor == mSensors[i]) {
defaultSensor =
reinterpret_cast<ASensorRef>(&mSensors[i]);
break;
}
}
});
(void)ret.isOk();
return defaultSensor;
}
ASensorRef ASensorManager::getDefaultSensorEx(
int /* type */, bool /* wakeup */) {
// XXX ISensorManager's getDefaultSensorEx() lacks a "wakeup" parameter.
return NULL;
}
ASensorEventQueue *ASensorManager::createEventQueue(
ALooper *looper, int ident, ALooper_callbackFunc callback, void *data) {
LOG(VERBOSE) << "ASensorManager::createEventQueue";
sp<ASensorEventQueue> queue =
new ASensorEventQueue(looper, ident, callback, data);
::android::hardware::setMinSchedulerPolicy(queue, SCHED_FIFO, 98);
Result result;
Return<void> ret =
mManager->createEventQueue(
queue, [&](const sp<IEventQueue> &queueImpl, auto tmpResult) {
result = tmpResult;
if (result != Result::OK) {
return;
}
queue->setImpl(queueImpl);
});
if (!ret.isOk() || result != Result::OK) {
LOG(ERROR) << "FAILED to create event queue";
return NULL;
}
queue->incStrong(NULL /* id */);
LOG(VERBOSE) << "Returning event queue " << queue.get();
return queue.get();
}
void ASensorManager::destroyEventQueue(ASensorEventQueue *queue) {
LOG(VERBOSE) << "ASensorManager::destroyEventQueue(" << queue << ")";
queue->invalidate();
queue->decStrong(NULL /* id */);
queue = NULL;
}
////////////////////////////////////////////////////////////////////////////////
ASensorManager *ASensorManager_getInstance() {
return ASensorManager::getInstance();
}
ASensorManager *ASensorManager_getInstanceForPackage(
const char* /* packageName */) {
return ASensorManager::getInstance();
}
#define RETURN_IF_MANAGER_IS_NULL(x) \
do { \
if (manager == NULL) { \
return x; \
} \
} while (0)
#define RETURN_IF_QUEUE_IS_NULL(x) \
do { \
if (queue == NULL) { \
return x; \
} \
} while (0)
#define RETURN_IF_SENSOR_IS_NULL(x) \
do { \
if (sensor == NULL) { \
return x; \
} \
} while (0)
int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list) {
RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
return manager->getSensorList(list);
}
ASensor const* ASensorManager_getDefaultSensor(
ASensorManager* manager, int type) {
RETURN_IF_MANAGER_IS_NULL(NULL);
return manager->getDefaultSensor(type);
}
#if 0
ASensor const* ASensorManager_getDefaultSensorEx(
ASensorManager* manager, int type, bool wakeUp) {
RETURN_IF_MANAGER_IS_NULL(NULL);
return manager->getDefaultSensorEx(type, wakeUp);
}
#endif
ASensorEventQueue* ASensorManager_createEventQueue(
ASensorManager* manager,
ALooper* looper,
int ident,
ALooper_callbackFunc callback,
void* data) {
RETURN_IF_MANAGER_IS_NULL(NULL);
if (looper == NULL) {
return NULL;
}
return manager->createEventQueue(looper, ident, callback, data);
}
int ASensorManager_destroyEventQueue(
ASensorManager* manager, ASensorEventQueue* queue) {
RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
manager->destroyEventQueue(queue);
queue = NULL;
return OK;
}
#if 0
int ASensorManager_createSharedMemoryDirectChannel(
ASensorManager* manager, int fd, size_t size) {
RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
return OK;
}
int ASensorManager_createHardwareBufferDirectChannel(
ASensorManager* manager, AHardwareBuffer const * buffer, size_t size) {
RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
return OK;
}
void ASensorManager_destroyDirectChannel(
ASensorManager* manager, int channelId) {
}
int ASensorManager_configureDirectReport(
ASensorManager* manager,
ASensor const* sensor,
int channelId,int rate) {
RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
return OK;
}
#endif
int ASensorEventQueue_registerSensor(
ASensorEventQueue* queue,
ASensor const* sensor,
int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs) {
LOG(VERBOSE) << "ASensorEventQueue_registerSensor";
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->registerSensor(
sensor, samplingPeriodUs, maxBatchReportLatencyUs);
}
int ASensorEventQueue_enableSensor(
ASensorEventQueue* queue, ASensor const* sensor) {
LOG(VERBOSE) << "ASensorEventQueue_enableSensor(queue " << queue << ")";
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->enableSensor(sensor);
}
int ASensorEventQueue_disableSensor(
ASensorEventQueue* queue, ASensor const* sensor) {
LOG(VERBOSE) << "ASensorEventQueue_disableSensor";
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->disableSensor(sensor);
}
int ASensorEventQueue_setEventRate(
ASensorEventQueue* queue,
ASensor const* sensor,
int32_t usec) {
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->setEventRate(sensor, usec);
}
int ASensorEventQueue_hasEvents(ASensorEventQueue* queue) {
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->hasEvents();
}
ssize_t ASensorEventQueue_getEvents(
ASensorEventQueue* queue, ASensorEvent* events, size_t count) {
LOG(VERBOSE) << "ASensorEventQueue_getEvents";
RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
return queue->getEvents(events, count);
}
const char *ASensor_getName(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(NULL);
return reinterpret_cast<const SensorInfo *>(sensor)->name.c_str();
}
const char *ASensor_getVendor(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(NULL);
return reinterpret_cast<const SensorInfo *>(sensor)->vendor.c_str();
}
int ASensor_getType(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_TYPE_INVALID);
return static_cast<int>(
reinterpret_cast<const SensorInfo *>(sensor)->type);
}
float ASensor_getResolution(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_RESOLUTION_INVALID);
return reinterpret_cast<const SensorInfo *>(sensor)->resolution;
}
int ASensor_getMinDelay(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_DELAY_INVALID);
return reinterpret_cast<const SensorInfo *>(sensor)->minDelay;
}
int ASensor_getFifoMaxEventCount(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID);
return reinterpret_cast<const SensorInfo *>(sensor)->fifoMaxEventCount;
}
int ASensor_getFifoReservedEventCount(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID);
return reinterpret_cast<const SensorInfo *>(sensor)->fifoReservedEventCount;
}
const char* ASensor_getStringType(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(NULL);
return reinterpret_cast<const SensorInfo *>(sensor)->typeAsString.c_str();
}
extern "C" float ASensor_getMaxRange(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(nanf(""));
return reinterpret_cast<const SensorInfo *>(sensor)->maxRange;
}
#if 0
int ASensor_getReportingMode(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(AREPORTING_MODE_INVALID);
return 0;
}
bool ASensor_isWakeUpSensor(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(false);
return false;
}
bool ASensor_isDirectChannelTypeSupported(
ASensor const* sensor, int channelType) {
RETURN_IF_SENSOR_IS_NULL(false);
return false;
}
int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor) {
RETURN_IF_SENSOR_IS_NULL(ASENSOR_DIRECT_RATE_STOP);
return 0;
}
#endif
static ALooper *getTheLooper() {
static ALooper *sLooper = NULL;
Mutex::Autolock autoLock(gLock);
if (sLooper == NULL) {
sLooper = new ALooper;
}
return sLooper;
}
ALooper *ALooper_forThread() {
LOG(VERBOSE) << "ALooper_forThread";
return getTheLooper();
}
ALooper *ALooper_prepare(int /* opts */) {
LOG(VERBOSE) << "ALooper_prepare";
return getTheLooper();
}
int ALooper_pollOnce(
int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int res = getTheLooper()->pollOnce(timeoutMillis, outFd, outEvents, outData);
LOG(VERBOSE) << "ALooper_pollOnce => " << res;
return res;
}
void ALooper_wake(ALooper* looper) {
LOG(VERBOSE) << "ALooper_wake";
looper->wake();
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef A_SENSOR_MANAGER_H_
#define A_SENSOR_MANAGER_H_
#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
#include <android/sensor.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
struct ALooper;
struct ASensorManager {
static ASensorManager *getInstance();
ASensorManager();
android::status_t initCheck() const;
// Returns error or number of sensors returned.
int getSensorList(ASensorList *list);
ASensorRef getDefaultSensor(int type);
ASensorRef getDefaultSensorEx(int type, bool wakeup);
ASensorEventQueue *createEventQueue(
ALooper *looper,
int ident,
ALooper_callbackFunc callback,
void *data);
void destroyEventQueue(ASensorEventQueue *queue);
private:
struct SensorDeathRecipient : public android::hardware::hidl_death_recipient
{
// hidl_death_recipient interface
virtual void serviceDied(uint64_t cookie,
const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override;
};
using ISensorManager = android::frameworks::sensorservice::V1_0::ISensorManager;
using SensorInfo = android::hardware::sensors::V1_0::SensorInfo;
static ASensorManager *sInstance;
android::sp<SensorDeathRecipient> mDeathRecipient = nullptr;
android::status_t mInitCheck;
android::sp<ISensorManager> mManager;
mutable android::Mutex mLock;
android::hardware::hidl_vec<SensorInfo> mSensors;
std::unique_ptr<ASensorRef[]> mSensorList;
DISALLOW_COPY_AND_ASSIGN(ASensorManager);
};
#endif // A_SENSOR_MANAGER_H_

View file

@ -0,0 +1,42 @@
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
cc_library_shared {
name: "libsensorndkbridge",
proprietary: true,
srcs: [
"ALooper.cpp",
"ASensorEventQueue.cpp",
"ASensorManager.cpp",
],
shared_libs: [
"libbase",
"libhidlbase",
"libhidltransport",
"libutils",
"android.frameworks.sensorservice@1.0",
"android.hardware.sensors@1.0",
],
static_libs: [
"android.hardware.sensors@1.0-convert",
],
header_libs: [
"libandroid_sensor_headers",
],
export_header_lib_headers: [
"libandroid_sensor_headers",
],
}

View file

@ -0,0 +1,9 @@
#!/bin/bash
source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
do_makefiles_update \
"android.frameworks:frameworks/hardware/interfaces" \
"android.hardware:hardware/interfaces" \
"android.hidl:system/libhidl/transport"

View file

@ -0,0 +1,66 @@
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "android.frameworks.vr.composer@1.0_hal",
srcs: [
"IVrComposerClient.hal",
],
}
genrule {
name: "android.frameworks.vr.composer@1.0_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.frameworks:frameworks/hardware/interfaces -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.vr.composer@1.0",
srcs: [
":android.frameworks.vr.composer@1.0_hal",
],
out: [
"android/frameworks/vr/composer/1.0/VrComposerClientAll.cpp",
],
}
genrule {
name: "android.frameworks.vr.composer@1.0_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.frameworks:frameworks/hardware/interfaces -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.frameworks.vr.composer@1.0",
srcs: [
":android.frameworks.vr.composer@1.0_hal",
],
out: [
"android/frameworks/vr/composer/1.0/IVrComposerClient.h",
"android/frameworks/vr/composer/1.0/IHwVrComposerClient.h",
"android/frameworks/vr/composer/1.0/BnHwVrComposerClient.h",
"android/frameworks/vr/composer/1.0/BpHwVrComposerClient.h",
"android/frameworks/vr/composer/1.0/BsVrComposerClient.h",
],
}
cc_library {
name: "android.frameworks.vr.composer@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.frameworks.vr.composer@1.0_genc++"],
generated_headers: ["android.frameworks.vr.composer@1.0_genc++_headers"],
export_generated_headers: ["android.frameworks.vr.composer@1.0_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.composer@2.1",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.composer@2.1",
],
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.frameworks.vr.composer@1.0;
import android.hardware.graphics.common@1.0::BufferUsage;
import android.hardware.graphics.common@1.0::PixelFormat;
import android.hardware.graphics.composer@2.1::IComposerClient;
interface IVrComposerClient
extends android.hardware.graphics.composer@2.1::IComposerClient {
/*
* Describes the metadata that describes the buffer.
*/
struct BufferMetadata {
/*
* Specifies how many columns of pixels are allocated in the buffer. The
* rows may be padded.
*/
uint32_t width;
/*
* Specifies how many rows of pixels are allocated in the buffer.
*/
uint32_t height;
/*
* Specifies the size of a row of pixels in the buffer. (width +
* padding).
*/
uint32_t stride;
/*
* The number of image layers allocated in the buffer.
*/
uint32_t layerCount;
/*
* Buffer pixel format.
*/
PixelFormat format;
/*
* Buffer usage mask.
*/
bitfield<BufferUsage> usage;
};
/*
* SET_LAYER_INFO has this pseudo prototype
*
* Used to annotate the layer with additional information, which must be
* used to describe the content of the layer (ie: notification, permission,
* etc) which allows VR window manager to treat certain layer types
* specially.
*
* @param display is the display on which the layer was created.
* @param layer is the layer affected by the change.
* @param layer_type the type of the layer as described by the window
* manager.
* @param application_id the application id the layer belongs to.
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_LAYER when an invalid layer handle was passed in.
*
* setLayerInfo(Display display,
* Layer layer,
* uint32_t layer_type,
* uint32_t application_id)
* generates(Error error);
*
* SET_CLIENT_TARGET_METADATA has this pseudo prototype
*
* Used to set the native buffer handle metadata required to import and use
* the buffer as a graphic buffer.
*
* @param display is the display on which the buffer is used.
* @param metadata is the buffer metadata required to import the buffer.
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* setClientTargetMetadata(Display display,
* BufferMetadata metadata)
* generates(Error error);
*
* SET_LAYER_BUFFER_METADATA has this pseudo prototype
*
* Used to set the native buffer handle metadata required to import and use
* the buffer as a graphic buffer.
*
* @param display is the display on which the buffer is used.
* @param layer is the layer the buffer metadata is associated with.
* @param metadata is the buffer metadata required to import the buffer.
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_LAYER when an invalid layer handle was passed in.
*
* setLayerBufferMetadata(Display display,
* Layer layer,
* BufferMetadata metadata)
* generates(Error error);
*/
enum VrCommand : android.hardware.graphics.composer@2.1::IComposerClient.Command {
SET_LAYER_INFO = 0x800 << OPCODE_SHIFT,
SET_CLIENT_TARGET_METADATA = 0x801 << OPCODE_SHIFT,
SET_LAYER_BUFFER_METADATA = 0x802 << OPCODE_SHIFT,
};
};