docs: Fixed doc comments to enable Doxygen to generate code block correctly. Test: Verified by manually generating docs. am: 5163357fc0
am: f4798f9e03
Change-Id: I0b75e6eeb3af2905a623b1a5b4f2ad2a59efdf52
diff --git a/cmds/bugreportz/Android.mk b/cmds/bugreportz/Android.mk
index 880bc75..10dda56 100644
--- a/cmds/bugreportz/Android.mk
+++ b/cmds/bugreportz/Android.mk
@@ -25,6 +25,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := bugreportz_test
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS := -Werror -Wall
diff --git a/cmds/bugreportz/AndroidTest.xml b/cmds/bugreportz/AndroidTest.xml
new file mode 100644
index 0000000..38b6276
--- /dev/null
+++ b/cmds/bugreportz/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for bugreportz_test">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="bugreportz_test->/data/local/tmp/bugreportz_test" />
+ </target_preparer>
+ <option name="test-suite-tag" value="apct" />
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="bugreportz_test" />
+ </test>
+</configuration>
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 18a4078..a1b6a51 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -138,7 +138,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := dumpstate_test_fixture
-
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS := $(COMMON_LOCAL_CFLAGS)
diff --git a/cmds/dumpstate/AndroidTest.xml b/cmds/dumpstate/AndroidTest.xml
new file mode 100644
index 0000000..f189489
--- /dev/null
+++ b/cmds/dumpstate/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for dumpstate_test_fixture">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="dumpstate_test_fixture->/data/local/tmp/dumpstate_test_fixture" />
+ </target_preparer>
+ <option name="test-suite-tag" value="apct" />
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="dumpstate_test_fixture" />
+ </test>
+</configuration>
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index d8a754c..6a81cfc 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -38,23 +38,21 @@
* frameworks/base/services/core/java/com/android/server/pm/Installer.java
***************************************************************************/
constexpr int DEXOPT_PUBLIC = 1 << 1;
-constexpr int DEXOPT_SAFEMODE = 1 << 2;
-constexpr int DEXOPT_DEBUGGABLE = 1 << 3;
-constexpr int DEXOPT_BOOTCOMPLETE = 1 << 4;
-constexpr int DEXOPT_PROFILE_GUIDED = 1 << 5;
-constexpr int DEXOPT_SECONDARY_DEX = 1 << 6;
+constexpr int DEXOPT_DEBUGGABLE = 1 << 2;
+constexpr int DEXOPT_BOOTCOMPLETE = 1 << 3;
+constexpr int DEXOPT_PROFILE_GUIDED = 1 << 4;
+constexpr int DEXOPT_SECONDARY_DEX = 1 << 5;
// DEXOPT_FORCE, DEXOPT_STORAGE_CE, DEXOPT_STORAGE_DE are exposed for secondary
// dex files only. Primary apks are analyzed in PackageManager and installd
// does not need to know if the compilation is forced or on what kind of storage
// the dex files are.
-constexpr int DEXOPT_FORCE = 1 << 7;
-constexpr int DEXOPT_STORAGE_CE = 1 << 8;
-constexpr int DEXOPT_STORAGE_DE = 1 << 9;
+constexpr int DEXOPT_FORCE = 1 << 6;
+constexpr int DEXOPT_STORAGE_CE = 1 << 7;
+constexpr int DEXOPT_STORAGE_DE = 1 << 8;
/* all known values for dexopt flags */
constexpr int DEXOPT_MASK =
DEXOPT_PUBLIC
- | DEXOPT_SAFEMODE
| DEXOPT_DEBUGGABLE
| DEXOPT_BOOTCOMPLETE
| DEXOPT_PROFILE_GUIDED
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index ff838ce..299ea17 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -472,7 +472,8 @@
case 6: {
// Version 1 had:
constexpr int OLD_DEXOPT_PUBLIC = 1 << 1;
- constexpr int OLD_DEXOPT_SAFEMODE = 1 << 2;
+ // Note: DEXOPT_SAFEMODE has been removed.
+ // constexpr int OLD_DEXOPT_SAFEMODE = 1 << 2;
constexpr int OLD_DEXOPT_DEBUGGABLE = 1 << 3;
constexpr int OLD_DEXOPT_BOOTCOMPLETE = 1 << 4;
constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
@@ -480,7 +481,6 @@
int input = atoi(param);
package_parameters_.dexopt_flags =
ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
- ReplaceMask(input, OLD_DEXOPT_SAFEMODE, DEXOPT_SAFEMODE) |
ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) |
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 39d92a7..d3d396f 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -46,7 +46,6 @@
cflags: [
"-DVENDORSERVICEMANAGER=1",
],
- shared_libs: ["libcutils"],
- static_libs: ["libselinux"],
+ shared_libs: ["libcutils", "libselinux_vendor"],
init_rc: ["vndservicemanager.rc"],
}
diff --git a/cmds/surfacereplayer/Android.bp b/cmds/surfacereplayer/Android.bp
new file mode 100644
index 0000000..d4c037a
--- /dev/null
+++ b/cmds/surfacereplayer/Android.bp
@@ -0,0 +1,4 @@
+subdirs = [
+ "proto",
+ "replayer",
+]
\ No newline at end of file
diff --git a/cmds/surfacereplayer/proto/Android.bp b/cmds/surfacereplayer/proto/Android.bp
new file mode 100644
index 0000000..dda80bb
--- /dev/null
+++ b/cmds/surfacereplayer/proto/Android.bp
@@ -0,0 +1,10 @@
+cc_library_static {
+ name: "libtrace_proto",
+ srcs: [
+ "src/trace.proto",
+ ],
+ proto: {
+ type: "lite",
+ export_proto_headers: true,
+ },
+}
diff --git a/cmds/surfacereplayer/proto/Android.mk b/cmds/surfacereplayer/proto/Android.mk
deleted file mode 100644
index 3cf1148..0000000
--- a/cmds/surfacereplayer/proto/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-proto-files-under, src)
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite
-
-LOCAL_MODULE := libtrace_proto
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/cmds/surfacereplayer/replayer/Android.bp b/cmds/surfacereplayer/replayer/Android.bp
new file mode 100644
index 0000000..5caceec
--- /dev/null
+++ b/cmds/surfacereplayer/replayer/Android.bp
@@ -0,0 +1,66 @@
+cc_library_shared {
+ name: "libsurfacereplayer",
+ clang: true,
+ srcs: [
+ "BufferQueueScheduler.cpp",
+ "Event.cpp",
+ "Replayer.cpp",
+ ],
+ cppflags: [
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wno-format",
+ "-Wno-c++98-compat-pedantic",
+ "-Wno-float-conversion",
+ "-Wno-disabled-macro-expansion",
+ "-Wno-float-equal",
+ "-Wno-sign-conversion",
+ "-Wno-padded",
+ "-std=c++14",
+ ],
+ static_libs: [
+ "libtrace_proto",
+ ],
+ shared_libs: [
+ "libEGL",
+ "libGLESv2",
+ "libbinder",
+ "liblog",
+ "libcutils",
+ "libgui",
+ "libui",
+ "libutils",
+ "libprotobuf-cpp-lite",
+ "libbase",
+ "libnativewindow",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+}
+
+cc_binary {
+ name: "surfacereplayer",
+ clang: true,
+ srcs: [
+ "Main.cpp",
+ ],
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ "libsurfacereplayer",
+ "libutils",
+ "libgui",
+ ],
+ static_libs: [
+ "libtrace_proto",
+ ],
+ cppflags: [
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wno-c++98-compat-pedantic",
+ "-Wno-float-conversion",
+ "-Wno-disabled-macro-expansion",
+ "-Wno-float-equal",
+ "-std=c++14",
+ ],
+}
diff --git a/cmds/surfacereplayer/replayer/Android.mk b/cmds/surfacereplayer/replayer/Android.mk
deleted file mode 100644
index 1dd926c..0000000
--- a/cmds/surfacereplayer/replayer/Android.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_TARGET_DIR := $(TARGET_OUT_DATA)/local/tmp
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(call first-makefiles-under, /frameworks/native/cmds/surfacereplayer/proto)
-
-include $(CLEAR_VARS)
-
-LOCAL_CPPFLAGS := -Weverything -Werror
-LOCAL_CPPFLAGS := -Wno-unused-parameter
-LOCAL_CPPFLAGS := -Wno-format
-
-LOCAL_MODULE := libsurfacereplayer
-
-LOCAL_SRC_FILES := \
- BufferQueueScheduler.cpp \
- Event.cpp \
- Replayer.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libEGL \
- libGLESv2 \
- libbinder \
- liblog \
- libcutils \
- libgui \
- libui \
- libutils \
- libprotobuf-cpp-lite \
- libbase \
- libnativewindow \
-
-LOCAL_STATIC_LIBRARIES := \
- libtrace_proto \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/..
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := surfacereplayer
-
-LOCAL_SRC_FILES := \
- Main.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libprotobuf-cpp-lite \
- libsurfacereplayer \
- libutils \
- libgui \
-
-LOCAL_STATIC_LIBRARIES := \
- libtrace_proto \
-
-LOCAL_CPPFLAGS := -Weverything -Werror
-LOCAL_CPPFLAGS := -Wno-unused-parameter
-
-LOCAL_MODULE_PATH := $(LOCAL_TARGET_DIR)
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/surfacereplayer/replayer/Main.cpp b/cmds/surfacereplayer/replayer/Main.cpp
index dd1dd7d..7090bdb 100644
--- a/cmds/surfacereplayer/replayer/Main.cpp
+++ b/cmds/surfacereplayer/replayer/Main.cpp
@@ -24,7 +24,7 @@
* 5. Exit successfully or print error statement
*/
-#include <replayer/Replayer.h>
+#include <Replayer.h>
#include <csignal>
#include <iostream>
diff --git a/cmds/vr/pose/Android.mk b/cmds/vr/pose/Android.mk
deleted file mode 100644
index 8be3214..0000000
--- a/cmds/vr/pose/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
- pose.cpp
-
-staticLibraries := \
- libdvrcommon \
- libvrsensor \
- libpdx_default_transport \
-
-sharedLibraries := \
- libcutils \
- liblog
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := pose
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/vr/pose/pose.cpp b/cmds/vr/pose/pose.cpp
deleted file mode 100644
index 2288a86..0000000
--- a/cmds/vr/pose/pose.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-// pose is a utility to query and manipulate the current pose via the pose
-// service.
-
-#include <cmath>
-#include <cstdio>
-#include <iomanip>
-#include <iostream>
-#include <regex>
-#include <vector>
-
-#include <private/dvr/types.h>
-#include <dvr/pose_client.h>
-
-using android::dvr::vec3;
-using android::dvr::quat;
-
-namespace {
-
-// Prints usage information to stderr.
-void PrintUsage(const char* executable_name) {
- std::cerr << "Usage: " << executable_name
- << " [--identity|--set=...|--unfreeze]\n"
- << "\n"
- << " no arguments: display the current pose.\n"
- << " --identity: freeze the pose to the identity pose.\n"
- << " --set=rx,ry,rz,rw[,px,py,pz]: freeze the pose to the given "
- "state. rx,ry,rz,rw are interpreted as rotation quaternion. "
- " px, py, pz as position (0,0,0 if omitted).\n"
- << " --mode=mode: sets mode to one of normal, head_turn:slow, "
- "head_turn:fast, rotate:slow, rotate:medium, rotate:fast, "
- "circle_strafe.\n"
- << " --unfreeze: sets the mode to normal.\n"
- << " --log_controller=[true|false]: starts and stops controller"
- " logs\n"
- << std::endl;
-}
-
-// If return_code is negative, print out its corresponding string description
-// and exit the program with a non-zero exit code.
-void ExitIfNegative(int return_code) {
- if (return_code < 0) {
- std::cerr << "Error: " << strerror(-return_code) << std::endl;
- std::exit(1);
- }
-}
-
-// Parses the following command line flags:
-// --identity
-// --set=rx,ry,rz,rw[,px,py,pz]
-// Returns false if parsing fails.
-bool ParseState(const std::string& arg, DvrPoseState* out_state) {
- if (arg == "--identity") {
- *out_state = {.head_from_start_rotation = {0.f, 0.f, 0.f, 1.f},
- .head_from_start_translation = {0.f, 0.f, 0.f},
- .timestamp_ns = 0,
- .sensor_from_start_rotation_velocity = {0.f, 0.f, 0.f}};
- return true;
- }
-
- const std::string prefix("--set=");
- if (arg.size() < 6 || arg.compare(0, prefix.size(), prefix) != 0) {
- return false;
- }
-
- // Tokenize by ','.
- std::regex split_by_comma("[,]+");
- std::sregex_token_iterator token_it(arg.begin() + prefix.size(), arg.end(),
- split_by_comma,
- -1 /* return inbetween parts */);
- std::sregex_token_iterator token_end;
-
- // Convert to float and store values.
- std::vector<float> values;
- for (; token_it != token_end; ++token_it) {
- std::string token = *(token_it);
- float value = 0.f;
- if (sscanf(token.c_str(), "%f", &value) != 1) {
- std::cerr << "Unable to parse --set value as float: " << token
- << std::endl;
- return false;
- } else {
- values.push_back(value);
- }
- }
-
- if (values.size() != 4 && values.size() != 7) {
- std::cerr << "Unable to parse --set, expected either 4 or 7 of values."
- << std::endl;
- return false;
- }
-
- float norm2 = values[0] * values[0] + values[1] * values[1] +
- values[2] * values[2] + values[3] * values[3];
- if (std::abs(norm2 - 1.f) > 1e-4) {
- if (norm2 < 1e-8) {
- std::cerr << "--set quaternion norm close to zero." << std::endl;
- return false;
- }
- float norm = std::sqrt(norm2);
- values[0] /= norm;
- values[1] /= norm;
- values[2] /= norm;
- values[3] /= norm;
- }
-
- out_state->head_from_start_rotation = {values[0], values[1], values[2],
- values[3]};
-
- if (values.size() == 7) {
- out_state->head_from_start_translation = {values[4], values[5], values[6]};
- } else {
- out_state->head_from_start_translation = {0.f, 0.f, 0.f};
- }
-
- out_state->timestamp_ns = 0;
- out_state->sensor_from_start_rotation_velocity = {0.f, 0.f, 0.f};
-
- return true;
-}
-
-// Parses the command line flag --mode.
-// Returns false if parsing fails.
-bool ParseSetMode(const std::string& arg, DvrPoseMode* mode) {
- const std::string prefix("--mode=");
- if (arg.size() < prefix.size() ||
- arg.compare(0, prefix.size(), prefix) != 0) {
- return false;
- }
-
- std::string value = arg.substr(prefix.size());
-
- if (value == "normal") {
- *mode = DVR_POSE_MODE_6DOF;
- return true;
- } else if (value == "head_turn:slow") {
- *mode = DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW;
- return true;
- } else if (value == "head_turn:fast") {
- *mode = DVR_POSE_MODE_MOCK_HEAD_TURN_FAST;
- return true;
- } else if (value == "rotate:slow") {
- *mode = DVR_POSE_MODE_MOCK_ROTATE_SLOW;
- return true;
- } else if (value == "rotate:medium") {
- *mode = DVR_POSE_MODE_MOCK_ROTATE_MEDIUM;
- return true;
- } else if (value == "rotate:fast") {
- *mode = DVR_POSE_MODE_MOCK_ROTATE_FAST;
- return true;
- } else if (value == "circle_strafe") {
- *mode = DVR_POSE_MODE_MOCK_CIRCLE_STRAFE;
- return true;
- } else {
- return false;
- }
-}
-
-// Parses the command line flag --controller_log.
-// Returns false if parsing fails.
-bool ParseLogController(const std::string& arg, bool* log_enabled) {
- const std::string prefix("--log_controller=");
- if (arg.size() < prefix.size() ||
- arg.compare(0, prefix.size(), prefix) != 0) {
- return false;
- }
-
- std::string value = arg.substr(prefix.size());
-
- if (value == "false") {
- *log_enabled = false;
- return true;
- } else if (value == "true") {
- *log_enabled = true;
- return true;
- } else {
- return false;
- }
-}
-
-// The different actions that the tool can perform.
-enum class Action {
- Query, // Query the current pose.
- Set, // Set the pose and freeze.
- Unfreeze, // Set the pose mode to normal.
- SetMode, // Sets the pose mode.
- LogController, // Start/stop controller logging in sensord.
-};
-
-// The action to perform when no arguments are passed to the tool.
-constexpr Action kDefaultAction = Action::Query;
-
-} // namespace
-
-int main(int argc, char** argv) {
- Action action = kDefaultAction;
- DvrPoseState state;
- DvrPoseMode pose_mode = DVR_POSE_MODE_6DOF;
- bool log_controller = false;
-
- // Parse command-line arguments.
- for (int i = 1; i < argc; ++i) {
- const std::string arg = argv[i];
- if (ParseState(arg, &state) && action == kDefaultAction) {
- action = Action::Set;
- } else if (arg == "--unfreeze" && action == kDefaultAction) {
- action = Action::Unfreeze;
- } else if (ParseSetMode(arg, &pose_mode) && action == kDefaultAction) {
- action = Action::SetMode;
- } else if (ParseLogController(arg, &log_controller)) {
- action = Action::LogController;
- } else {
- PrintUsage(argv[0]);
- return 1;
- }
- }
-
- auto pose_client = dvrPoseCreate();
- if (!pose_client) {
- std::cerr << "Unable to create pose client." << std::endl;
- return 1;
- }
-
- switch (action) {
- case Action::Query: {
- ExitIfNegative(dvrPosePoll(pose_client, &state));
- uint64_t timestamp = state.timestamp_ns;
- const auto& rotation = state.head_from_start_rotation;
- const auto& translation = state.head_from_start_translation;
- const auto& rotation_velocity = state.sensor_from_start_rotation_velocity;
- quat q(rotation.w, rotation.x, rotation.y, rotation.z);
- vec3 angles = q.matrix().eulerAngles(0, 1, 2);
- angles = angles * 180.f / M_PI;
- vec3 x = q * vec3(1.0f, 0.0f, 0.0f);
- vec3 y = q * vec3(0.0f, 1.0f, 0.0f);
- vec3 z = q * vec3(0.0f, 0.0f, 1.0f);
-
- std::cout << "timestamp_ns: " << timestamp << std::endl
- << "rotation_quaternion: " << rotation.x << ", " << rotation.y
- << ", " << rotation.z << ", " << rotation.w << std::endl
- << "rotation_angles: " << angles.x() << ", " << angles.y()
- << ", " << angles.z() << std::endl
- << "translation: " << translation.x << ", " << translation.y
- << ", " << translation.z << std::endl
- << "rotation_velocity: " << rotation_velocity.x << ", "
- << rotation_velocity.y << ", " << rotation_velocity.z
- << std::endl
- << "axes: " << std::setprecision(3)
- << "x(" << x.x() << ", " << x.y() << ", " << x.z() << "), "
- << "y(" << y.x() << ", " << y.y() << ", " << y.z() << "), "
- << "z(" << z.x() << ", " << z.y() << ", " << z.z() << "), "
- << std::endl;
- break;
- }
- case Action::Set: {
- ExitIfNegative(dvrPoseFreeze(pose_client, &state));
- break;
- }
- case Action::Unfreeze: {
- ExitIfNegative(dvrPoseSetMode(pose_client, DVR_POSE_MODE_6DOF));
- break;
- }
- case Action::SetMode: {
- ExitIfNegative(dvrPoseSetMode(pose_client, pose_mode));
- break;
- }
- case Action::LogController: {
- ExitIfNegative(
- dvrPoseLogController(pose_client, log_controller));
- break;
- }
- }
-
- dvrPoseDestroy(pose_client);
-}
diff --git a/data/etc/android.hardware.radio.xml b/data/etc/android.hardware.radio.xml
new file mode 100644
index 0000000..f718c47
--- /dev/null
+++ b/data/etc/android.hardware.radio.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard set of features for a broadcast radio. -->
+<permissions>
+ <feature name="android.hardware.radio" />
+</permissions>
diff --git a/data/etc/android.hardware.telephony.euicc.xml b/data/etc/android.hardware.telephony.euicc.xml
new file mode 100644
index 0000000..167ed6a
--- /dev/null
+++ b/data/etc/android.hardware.telephony.euicc.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Feature for devices with an eUICC. -->
+<permissions>
+ <feature name="android.hardware.telephony.euicc" />
+</permissions>
diff --git a/data/etc/android.hardware.wifi.passpoint.xml b/data/etc/android.hardware.wifi.passpoint.xml
new file mode 100644
index 0000000..4698bb3
--- /dev/null
+++ b/data/etc/android.hardware.wifi.passpoint.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device includes WiFi Passpoint. -->
+<permissions>
+ <feature name="android.hardware.wifi.passpoint" />
+</permissions>
diff --git a/include/ui/DebugUtils.h b/include/ui/DebugUtils.h
index 8483808..30f4a59 100644
--- a/include/ui/DebugUtils.h
+++ b/include/ui/DebugUtils.h
@@ -17,6 +17,7 @@
#pragma once
#include <system/graphics.h>
+#include <ui/PixelFormat.h>
#include <string>
@@ -25,3 +26,4 @@
std::string decodeRange(android_dataspace dataspace);
std::string dataspaceDetails(android_dataspace dataspace);
std::string decodeColorMode(android_color_mode colormode);
+std::string decodePixelFormat(android::PixelFormat format);
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp
index 0d25176..a20154f 100644
--- a/libs/arect/Android.bp
+++ b/libs/arect/Android.bp
@@ -23,5 +23,6 @@
cc_library_static {
name: "libarect",
host_supported: true,
+ vendor_available: true,
export_include_dirs: ["include"],
}
diff --git a/libs/math/Android.bp b/libs/math/Android.bp
index 3ef8b4a..693bace 100644
--- a/libs/math/Android.bp
+++ b/libs/math/Android.bp
@@ -15,6 +15,7 @@
cc_library_static {
name: "libmath",
host_supported: true,
+ vendor_available: true,
export_include_dirs: ["include"],
}
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index d759acb..938d426 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -63,4 +63,11 @@
],
}
+llndk_library {
+ name: "libnativewindow",
+ symbol_file: "libnativewindow.map.vndk.txt",
+ unversioned: true,
+ export_include_dirs: ["include"],
+}
+
subdirs = ["tests"]
diff --git a/libs/nativewindow/libnativewindow.map.vndk.txt b/libs/nativewindow/libnativewindow.map.vndk.txt
new file mode 100644
index 0000000..eed4e19
--- /dev/null
+++ b/libs/nativewindow/libnativewindow.map.vndk.txt
@@ -0,0 +1,44 @@
+LIBNATIVEWINDOW {
+ global:
+ AHardwareBuffer_acquire;
+ AHardwareBuffer_allocate;
+ AHardwareBuffer_describe;
+ AHardwareBuffer_fromHardwareBuffer;
+ AHardwareBuffer_getNativeHandle;
+ AHardwareBuffer_lock;
+ AHardwareBuffer_recvHandleFromUnixSocket;
+ AHardwareBuffer_release;
+ AHardwareBuffer_sendHandleToUnixSocket;
+ AHardwareBuffer_toHardwareBuffer;
+ AHardwareBuffer_unlock;
+ ANativeWindowBuffer_getHardwareBuffer;
+ ANativeWindow_OemStorageGet;
+ ANativeWindow_OemStorageSet;
+ ANativeWindow_acquire;
+ ANativeWindow_cancelBuffer;
+ ANativeWindow_dequeueBuffer;
+ ANativeWindow_fromSurface;
+ ANativeWindow_fromSurfaceTexture;
+ ANativeWindow_getFormat;
+ ANativeWindow_getHeight;
+ ANativeWindow_getWidth;
+ ANativeWindow_lock;
+ ANativeWindow_query;
+ ANativeWindow_queryf;
+ ANativeWindow_queueBuffer;
+ ANativeWindow_release;
+ ANativeWindow_setAutoRefresh;
+ ANativeWindow_setBufferCount;
+ ANativeWindow_setBufferDataSpace;
+ ANativeWindow_setBuffersDimensions;
+ ANativeWindow_setBuffersFormat;
+ ANativeWindow_setBuffersGeometry;
+ ANativeWindow_setBuffersTimestamp;
+ ANativeWindow_setBuffersTransform;
+ ANativeWindow_setSharedBufferMode;
+ ANativeWindow_setSwapInterval;
+ ANativeWindow_setUsage;
+ ANativeWindow_unlockAndPost;
+ local:
+ *;
+};
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 5ccf178..ab48a7f 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -65,7 +65,7 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.configstore@1.0",
- "android.hardware.configstore-utils",
+ "android.hardware.configstore-utils",
"libbase",
"libnativeloader",
"libcutils",
diff --git a/libs/ui/DebugUtils.cpp b/libs/ui/DebugUtils.cpp
index 882bd7c..94b68e7 100644
--- a/libs/ui/DebugUtils.cpp
+++ b/libs/ui/DebugUtils.cpp
@@ -15,6 +15,7 @@
*/
#include <ui/DebugUtils.h>
+#include <ui/PixelFormat.h>
#include <android-base/stringprintf.h>
#include <string>
@@ -145,6 +146,9 @@
}
std::string dataspaceDetails(android_dataspace dataspace) {
+ if (dataspace == 0) {
+ return "Default (0)";
+ }
return android::base::StringPrintf("%s %s %s", decodeStandard(dataspace).c_str(),
decodeTransfer(dataspace).c_str(),
decodeRange(dataspace).c_str());
@@ -185,3 +189,36 @@
return android::base::StringPrintf("Unknown color mode %d", colorMode);
}
+
+// Converts a PixelFormat to a human-readable string. Max 11 chars.
+// (Could use a table of prefab String8 objects.)
+std::string decodePixelFormat(android::PixelFormat format) {
+ switch (format) {
+ case android::PIXEL_FORMAT_UNKNOWN:
+ return std::string("Unknown/None");
+ case android::PIXEL_FORMAT_CUSTOM:
+ return std::string("Custom");
+ case android::PIXEL_FORMAT_TRANSLUCENT:
+ return std::string("Translucent");
+ case android::PIXEL_FORMAT_TRANSPARENT:
+ return std::string("Transparent");
+ case android::PIXEL_FORMAT_OPAQUE:
+ return std::string("Opaque");
+ case android::PIXEL_FORMAT_RGBA_8888:
+ return std::string("RGBA_8888");
+ case android::PIXEL_FORMAT_RGBX_8888:
+ return std::string("RGBx_8888");
+ case android::PIXEL_FORMAT_RGBA_FP16:
+ return std::string("RGBA_FP16");
+ case android::PIXEL_FORMAT_RGBA_1010102:
+ return std::string("RGBA_1010102");
+ case android::PIXEL_FORMAT_RGB_888:
+ return std::string("RGB_888");
+ case android::PIXEL_FORMAT_RGB_565:
+ return std::string("RGB_565");
+ case android::PIXEL_FORMAT_BGRA_8888:
+ return std::string("BGRA_8888");
+ default:
+ return android::base::StringPrintf("Unknown %#08x", format);
+ }
+}
diff --git a/libs/vr/libvrsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h
index ed75f84..6802fa9 100644
--- a/libs/vr/libvrsensor/include/dvr/pose_client.h
+++ b/libs/vr/libvrsensor/include/dvr/pose_client.h
@@ -105,6 +105,8 @@
DVR_POSE_MODE_MOCK_ROTATE_MEDIUM,
DVR_POSE_MODE_MOCK_ROTATE_FAST,
DVR_POSE_MODE_MOCK_CIRCLE_STRAFE,
+ DVR_POSE_MODE_FLOAT,
+ DVR_POSE_MODE_MOCK_MOTION_SICKNESS,
// Always last.
DVR_POSE_MODE_COUNT,
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index d0996f0..7de8c62 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -625,6 +625,11 @@
#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
#endif
+#ifndef EGL_KHR_no_config_context
+#define EGL_KHR_no_config_context 1
+#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0)
+#endif /* EGL_KHR_no_config_context */
+
#ifndef EGL_ANDROID_get_frame_timestamps
#define EGL_ANDROID_get_frame_timestamps 1
#define EGL_TIMESTAMPS_ANDROID 0x3430
@@ -667,6 +672,16 @@
#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340
#endif /* EGL_EXT_gl_colorspace_bt2020_pq */
+#ifndef EGL_EXT_gl_colorspace_display_p3
+#define EGL_EXT_gl_colorspace_display_p3 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363
+#endif /* EGL_EXT_gl_colorspace_display_p3 */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_linear
+#define EGL_EXT_gl_colorspace_display_p3_linear 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362
+#endif /* EGL_EXT_gl_colorspace_display_p3_linear */
+
#ifndef EGL_EXT_gl_colorspace_scrgb_linear
#define EGL_EXT_gl_colorspace_scrgb_linear 1
#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 9de15d0..27a45e0 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -79,6 +79,7 @@
extern char const * const gBuiltinExtensionString;
extern char const * const gExtensionString;
+// clang-format off
char const * const gBuiltinExtensionString =
"EGL_KHR_get_all_proc_addresses "
"EGL_ANDROID_presentation_time "
@@ -86,6 +87,9 @@
"EGL_ANDROID_get_native_client_buffer "
"EGL_ANDROID_front_buffer_auto_refresh "
"EGL_ANDROID_get_frame_timestamps "
+ "EGL_EXT_gl_colorspace_scrgb_linear "
+ "EGL_EXT_gl_colorspace_display_p3_linear "
+ "EGL_EXT_gl_colorspace_display_p3 "
;
char const * const gExtensionString =
@@ -123,6 +127,7 @@
"EGL_IMG_context_priority "
"EGL_KHR_no_config_context "
;
+// clang-format on
// extensions not exposed to applications but used by the ANDROID system
// "EGL_ANDROID_blob_cache " // strongly recommended
@@ -458,10 +463,57 @@
return HAL_DATASPACE_SRGB_LINEAR;
} else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
return HAL_DATASPACE_SRGB;
+ } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
+ return HAL_DATASPACE_DISPLAY_P3;
+ } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
+ return HAL_DATASPACE_DISPLAY_P3_LINEAR;
+ } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
+ return HAL_DATASPACE_V0_SCRGB_LINEAR;
}
return dataSpace;
}
+static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
+ EGLint& colorSpace, android_dataspace& dataSpace) {
+ colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+ dataSpace = HAL_DATASPACE_UNKNOWN;
+ if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
+ for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
+ if (*attr == EGL_GL_COLORSPACE_KHR) {
+ colorSpace = attr[1];
+ bool found = false;
+ // Verify that color space is allowed
+ if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
+ colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
+ found = true;
+ } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
+ found = true;
+ }
+ if (!found) {
+ return false;
+ }
+ // Only change the dataSpace from default if the application
+ // has explicitly set the color space with a EGL_GL_COLORSPACE_KHR attribute.
+ dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
+ }
+ }
+ }
+ return true;
+}
+
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window,
const EGLint *attrib_list)
@@ -502,7 +554,8 @@
&componentType);
EGLint format;
- android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+ EGLint colorSpace;
+ android_dataspace dataSpace;
EGLint a = 0;
EGLint r, g, b;
r = g = b = 0;
@@ -539,12 +592,9 @@
}
// now select a corresponding sRGB format if needed
- if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
- for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
- if (*attr == EGL_GL_COLORSPACE_KHR) {
- dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
- }
- }
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
if (format != 0) {
@@ -575,8 +625,8 @@
EGLSurface surface = cnx->egl.eglCreateWindowSurface(
iDpy, config, window, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
- surface, cnx);
+ egl_surface_t* s =
+ new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
return s;
}
@@ -595,12 +645,19 @@
egl_connection_t* cnx = NULL;
egl_display_ptr dp = validate_display_connection(dpy, cnx);
+ EGLint colorSpace;
+ android_dataspace dataSpace;
if (dp) {
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
dp->disp.dpy, config, pixmap, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
@@ -614,12 +671,19 @@
egl_connection_t* cnx = NULL;
egl_display_ptr dp = validate_display_connection(dpy, cnx);
+ EGLint colorSpace;
+ android_dataspace dataSpace;
if (dp) {
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
dp->disp.dpy, config, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
@@ -658,6 +722,10 @@
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
egl_surface_t const * const s = get_surface(surface);
+ if (attribute == EGL_GL_COLORSPACE_KHR) {
+ *value = s->getColorSpace();
+ return EGL_TRUE;
+ }
return s->cnx->egl.eglQuerySurface(
dp->disp.dpy, s->surface, attribute, value);
}
@@ -1697,13 +1765,22 @@
egl_display_ptr dp = validate_display(dpy);
if (!dp) return EGL_NO_SURFACE;
+ EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+ android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+ // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to
+ // indicate support for EGL_GL_COLORSPACE_KHR.
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
dp->disp.dpy, config, stream, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 6238780..837cfa9 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -55,12 +55,15 @@
// ----------------------------------------------------------------------------
-egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config,
- EGLNativeWindowType win, EGLSurface surface,
- egl_connection_t const* cnx) :
- egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx),
- connected(true)
-{
+egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win,
+ EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx)
+ : egl_object_t(dpy),
+ surface(surface),
+ config(config),
+ win(win),
+ cnx(cnx),
+ connected(true),
+ colorSpace(colorSpace) {
if (win) {
win->incStrong(this);
}
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 8988905..7c3075c 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -131,12 +131,12 @@
public:
typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
- egl_surface_t(egl_display_t* dpy, EGLConfig config,
- EGLNativeWindowType win, EGLSurface surface,
- egl_connection_t const* cnx);
+ egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface,
+ EGLint colorSpace, egl_connection_t const* cnx);
ANativeWindow* getNativeWindow() { return win; }
ANativeWindow* getNativeWindow() const { return win; }
+ EGLint getColorSpace() const { return colorSpace; }
// Try to keep the order of these fields and size unchanged. It's not public API, but
// it's not hard to imagine native games accessing them.
@@ -149,6 +149,7 @@
private:
bool connected;
void disconnect();
+ EGLint colorSpace;
};
class egl_context_t: public egl_object_t {
diff --git a/opengl/tests/Android.bp b/opengl/tests/Android.bp
new file mode 100644
index 0000000..bf7aeb1
--- /dev/null
+++ b/opengl/tests/Android.bp
@@ -0,0 +1,4 @@
+subdirs = [
+ "hwc",
+ "lib",
+]
diff --git a/opengl/tests/Android.mk b/opengl/tests/Android.mk
index 3ae3b4e..92d223c 100644
--- a/opengl/tests/Android.mk
+++ b/opengl/tests/Android.mk
@@ -12,7 +12,6 @@
gl_perf \
gl_yuvtex \
gralloc \
- hwc \
include \
lib \
linetex \
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 94de5af..4c13dc8 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -28,18 +28,17 @@
#include <gui/IGraphicBufferConsumer.h>
#include <gui/BufferQueue.h>
-#define PIXEL_FORMAT_FLOAT "EGL_EXT_pixel_format_float"
-
-bool hasEglPixelFormatFloat() {
- EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
- size_t cropExtLen = strlen(PIXEL_FORMAT_FLOAT);
+ size_t cropExtLen = strlen(extensionName);
size_t extsLen = strlen(exts);
- bool equal = !strcmp(PIXEL_FORMAT_FLOAT, exts);
- bool atStart = !strncmp(PIXEL_FORMAT_FLOAT " ", exts, cropExtLen + 1);
+ bool equal = !strcmp(extensionName, exts);
+ android::String8 extString(extensionName);
+ android::String8 space(" ");
+ bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
bool atEnd = (cropExtLen + 1) < extsLen &&
- !strcmp(" " PIXEL_FORMAT_FLOAT, exts + extsLen - (cropExtLen + 1));
- bool inMiddle = strstr(exts, " " PIXEL_FORMAT_FLOAT " ");
+ !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
+ bool inMiddle = strstr(exts, space + extString + space);
return equal || atStart || atEnd || inMiddle;
}
@@ -193,6 +192,176 @@
EXPECT_GE(components[3], 8);
}
+TEST_F(EGLTest, EGLDisplayP3) {
+ EGLint numConfigs;
+ EGLConfig config;
+ EGLBoolean success;
+
+ if (!hasWideColorDisplay) {
+ // skip this test if device does not have wide-color display
+ return;
+ }
+
+ // Test that display-p3 extensions exist
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
+
+ // Use 8-bit to keep forcus on Display-P3 aspect
+ EGLint attrs[] = {
+ // clang-format off
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
+ success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(1, numConfigs);
+
+ EGLint components[4];
+ EGLint value;
+ eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
+
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ EXPECT_EQ(components[0], 8);
+ EXPECT_EQ(components[1], 8);
+ EXPECT_EQ(components[2], 8);
+ EXPECT_EQ(components[3], 8);
+
+ struct DummyConsumer : public BnConsumerListener {
+ void onFrameAvailable(const BufferItem& /* item */) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+
+ // Create a EGLSurface
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ consumer->consumerConnect(new DummyConsumer, false);
+ sp<Surface> mSTC = new Surface(producer);
+ sp<ANativeWindow> mANW = mSTC;
+ EGLint winAttrs[] = {
+ // clang-format off
+ EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
+
+ EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, eglSurface);
+
+ success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
+
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
+}
+
+TEST_F(EGLTest, EGLDisplayP31010102) {
+ EGLint numConfigs;
+ EGLConfig config;
+ EGLBoolean success;
+
+ if (!hasWideColorDisplay) {
+ // skip this test if device does not have wide-color display
+ return;
+ }
+
+ // Test that display-p3 extensions exist
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
+
+ // Use 8-bit to keep forcus on Display-P3 aspect
+ EGLint attrs[] = {
+ // clang-format off
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_RED_SIZE, 10,
+ EGL_GREEN_SIZE, 10,
+ EGL_BLUE_SIZE, 10,
+ EGL_ALPHA_SIZE, 2,
+ EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
+ success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(1, numConfigs);
+
+ EGLint components[4];
+ EGLint value;
+ eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
+
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ EXPECT_EQ(components[0], 10);
+ EXPECT_EQ(components[1], 10);
+ EXPECT_EQ(components[2], 10);
+ EXPECT_EQ(components[3], 2);
+
+ struct DummyConsumer : public BnConsumerListener {
+ void onFrameAvailable(const BufferItem& /* item */) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+
+ // Create a EGLSurface
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ consumer->consumerConnect(new DummyConsumer, false);
+ sp<Surface> mSTC = new Surface(producer);
+ sp<ANativeWindow> mANW = mSTC;
+ EGLint winAttrs[] = {
+ // clang-format off
+ EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
+
+ EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, eglSurface);
+
+ success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
+
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
+}
+
TEST_F(EGLTest, EGLConfigFP16) {
EGLint numConfigs;
EGLConfig config;
@@ -203,23 +372,20 @@
return;
}
- ASSERT_TRUE(hasEglPixelFormatFloat());
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
- EGLint attrs[] = {EGL_SURFACE_TYPE,
- EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE,
- EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE,
- 16,
- EGL_GREEN_SIZE,
- 16,
- EGL_BLUE_SIZE,
- 16,
- EGL_ALPHA_SIZE,
- 16,
- EGL_COLOR_COMPONENT_TYPE_EXT,
- EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
- EGL_NONE};
+ EGLint attrs[] = {
+ // clang-format off
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 16,
+ EGL_GREEN_SIZE, 16,
+ EGL_BLUE_SIZE, 16,
+ EGL_ALPHA_SIZE, 16,
+ EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
ASSERT_EQ(1, numConfigs);
@@ -250,6 +416,108 @@
void onSidebandStreamChanged() override {}
};
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ consumer->consumerConnect(new DummyConsumer, false);
+ sp<Surface> mSTC = new Surface(producer);
+ sp<ANativeWindow> mANW = mSTC;
+
+ EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, eglSurface);
+
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
+}
+
+TEST_F(EGLTest, EGL_KHR_no_config_context) {
+ if (!hasWideColorDisplay) {
+ // skip this test if device does not have wide-color display
+ return;
+ }
+
+ ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
+
+ struct DummyConsumer : public BnConsumerListener {
+ void onFrameAvailable(const BufferItem& /* item */) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+
+ std::vector<EGLint> contextAttributes;
+ contextAttributes.reserve(4);
+ contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
+ contextAttributes.push_back(2);
+ contextAttributes.push_back(EGL_NONE);
+ contextAttributes.push_back(EGL_NONE);
+
+ EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
+ contextAttributes.data());
+ EXPECT_NE(EGL_NO_CONTEXT, eglContext);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+
+ if (eglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(mEglDisplay, eglContext);
+ }
+}
+
+// Emulate what a native application would do to create a
+// 10:10:10:2 surface.
+TEST_F(EGLTest, EGLConfig1010102) {
+ EGLint numConfigs;
+ EGLConfig config;
+ EGLBoolean success;
+
+ if (!hasWideColorDisplay) {
+ // skip this test if device does not have wide-color display
+ return;
+ }
+
+ EGLint attrs[] = {
+ // clang-format off
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_RED_SIZE, 10,
+ EGL_GREEN_SIZE, 10,
+ EGL_BLUE_SIZE, 10,
+ EGL_ALPHA_SIZE, 2,
+ EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
+ EGL_NONE, EGL_NONE
+ // clang-format on
+ };
+ success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(1, numConfigs);
+
+ EGLint components[4];
+ EGLint value;
+ eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
+
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
+ ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ EXPECT_EQ(components[0], 10);
+ EXPECT_EQ(components[1], 10);
+ EXPECT_EQ(components[2], 10);
+ EXPECT_EQ(components[3], 2);
+
+ struct DummyConsumer : public BnConsumerListener {
+ void onFrameAvailable(const BufferItem& /* item */) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+
// Create a EGLSurface
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
diff --git a/opengl/tests/configdump/configdump.cpp b/opengl/tests/configdump/configdump.cpp
index 2a94598..c423105 100644
--- a/opengl/tests/configdump/configdump.cpp
+++ b/opengl/tests/configdump/configdump.cpp
@@ -66,8 +66,7 @@
};
// clang-format on
-int main(int argc, char** argv)
-{
+int main(int /*argc*/, char** /*argv*/) {
EGLConfig* configs;
EGLint n;
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 9f8d166..ee88667 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -30,6 +30,7 @@
#include <EGLUtils.h>
using namespace android;
+EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
static void printGLString(const char *name, GLenum s) {
// fprintf(stderr, "printGLString %s, %d\n", name, s);
@@ -46,7 +47,8 @@
static void printEGLString(EGLDisplay dpy, const char *name, GLenum s) {
const char *v = (const char *) eglQueryString(dpy, s);
- fprintf(stderr, "GL %s = %s\n", name, v);
+ const char* va = (const char*)eglQueryStringImplementationANDROID(dpy, s);
+ fprintf(stderr, "GL %s = %s\nImplementationANDROID: %s\n", name, v, va);
}
static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
@@ -263,7 +265,7 @@
return true;
}
-int main(int argc, char** argv) {
+int main(int /*argc*/, char** /*argv*/) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};
diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
index 98d8aa8..22128ab 100644
--- a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
+++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
@@ -331,7 +331,7 @@
printf("\n");
}
-int main(int argc, char** argv) {
+int main(int /*argc*/, char** /*argv*/) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};
diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
index c923b07..fad26a6 100644
--- a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
+++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
@@ -221,7 +221,7 @@
printf("\n");
}
-int main(int argc, char** argv) {
+int main(int /*argc*/, char** /*argv*/) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};
diff --git a/opengl/tests/hwc/Android.bp b/opengl/tests/hwc/Android.bp
new file mode 100644
index 0000000..b6e6f0e
--- /dev/null
+++ b/opengl/tests/hwc/Android.bp
@@ -0,0 +1,102 @@
+// Copyright (C) 2010 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_defaults {
+
+ name: "hwc_tests_defaults",
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-DEGL_EGLEXT_PROTOTYPES",
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+}
+
+cc_library_static {
+
+ name: "libhwcTest",
+ srcs: ["hwcTestLib.cpp"],
+
+ static_libs: [
+ "libarect",
+ "libglTest",
+ "libtestUtil",
+ ],
+ defaults: ["hwc_tests_defaults"],
+}
+
+cc_defaults {
+
+ name: "hwc_lib_defaults",
+ shared_libs: [
+ "libcutils",
+ "libEGL",
+ "libGLESv2",
+ "libhardware",
+ "liblog",
+ "libui",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libglTest",
+ "libhwcTest",
+ "libtestUtil",
+ ],
+}
+
+cc_test {
+
+ name: "hwcStress",
+ srcs: ["hwcStress.cpp"],
+
+ defaults: [
+ "hwc_lib_defaults",
+ "hwc_tests_defaults",
+ ],
+}
+
+cc_test {
+
+ name: "hwcRects",
+ srcs: ["hwcRects.cpp"],
+
+ defaults: [
+ "hwc_lib_defaults",
+ "hwc_tests_defaults",
+ ],
+}
+
+cc_test {
+
+ name: "hwcColorEquiv",
+ srcs: ["hwcColorEquiv.cpp"],
+
+ defaults: [
+ "hwc_lib_defaults",
+ "hwc_tests_defaults",
+ ],
+}
+
+cc_test {
+
+ name: "hwcCommit",
+ srcs: ["hwcCommit.cpp"],
+
+ defaults: [
+ "hwc_lib_defaults",
+ "hwc_tests_defaults",
+ ],
+}
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
deleted file mode 100644
index 13337c2..0000000
--- a/opengl/tests/hwc/Android.mk
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE:= libhwcTest
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-LOCAL_CXX_STL := libc++
-LOCAL_SRC_FILES:= hwcTestLib.cpp
-LOCAL_C_INCLUDES += system/extras/tests/include \
- $(call include-path-for, opengl-tests-includes) \
-
-LOCAL_STATIC_LIBRARIES := libarect
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE:= hwcStress
-LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-LOCAL_CXX_STL := libc++
-LOCAL_SRC_FILES:= hwcStress.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libEGL \
- libGLESv2 \
- libutils \
- liblog \
- libui \
- libhardware \
-
-LOCAL_STATIC_LIBRARIES := \
- libtestUtil \
- libglTest \
- libhwcTest \
-
-LOCAL_C_INCLUDES += \
- system/extras/tests/include \
- hardware/libhardware/include \
- $(call include-path-for, opengl-tests-includes) \
-
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE:= hwcRects
-LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-LOCAL_CXX_STL := libc++
-LOCAL_SRC_FILES:= hwcRects.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libEGL \
- libGLESv2 \
- libutils \
- liblog \
- libui \
- libhardware \
-
-LOCAL_STATIC_LIBRARIES := \
- libtestUtil \
- libglTest \
- libhwcTest \
-
-LOCAL_C_INCLUDES += \
- system/extras/tests/include \
- hardware/libhardware/include \
- $(call include-path-for, opengl-tests-includes) \
-
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE:= hwcColorEquiv
-LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-LOCAL_CXX_STL := libc++
-LOCAL_SRC_FILES:= hwcColorEquiv.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libEGL \
- libGLESv2 \
- libutils \
- liblog \
- libui \
- libhardware \
-
-LOCAL_STATIC_LIBRARIES := \
- libtestUtil \
- libglTest \
- libhwcTest \
-
-LOCAL_C_INCLUDES += \
- system/extras/tests/include \
- hardware/libhardware/include \
- $(call include-path-for, opengl-tests-includes) \
-
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE:= hwcCommit
-LOCAL_MODULE_TAGS := tests
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-LOCAL_CXX_STL := libc++
-LOCAL_SRC_FILES:= hwcCommit.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libEGL \
- libGLESv2 \
- libutils \
- liblog \
- libui \
- libhardware \
-
-LOCAL_STATIC_LIBRARIES := \
- libtestUtil \
- libglTest \
- libhwcTest \
-
-LOCAL_C_INCLUDES += \
- system/extras/tests/include \
- hardware/libhardware/include \
- $(call include-path-for, opengl-tests-includes) \
-
-include $(BUILD_NATIVE_TEST)
diff --git a/opengl/tests/lib/Android.bp b/opengl/tests/lib/Android.bp
new file mode 100644
index 0000000..2f6095d
--- /dev/null
+++ b/opengl/tests/lib/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2010 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_static {
+
+ name: "libglTest",
+ srcs: [
+ "glTestLib.cpp",
+ "WindowSurface.cpp",
+ ],
+ export_include_dirs: ["include"],
+
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-DEGL_EGLEXT_PROTOTYPES",
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+
+ shared_libs: ["libgui"],
+ static_libs: [
+ "libarect",
+ "libtestUtil",
+ ],
+
+}
diff --git a/opengl/tests/lib/Android.mk b/opengl/tests/lib/Android.mk
deleted file mode 100644
index ea94bc1..0000000
--- a/opengl/tests/lib/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE:= libglTest
-LOCAL_SRC_FILES:= glTestLib.cpp WindowSurface.cpp
-LOCAL_C_INCLUDES += system/extras/tests/include \
- $(call include-path-for, opengl-tests-includes)
-
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wall -Wextra -Werror
-
-LOCAL_SHARED_LIBRARIES += libgui
-LOCAL_STATIC_LIBRARIES := libarect
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/opengl/tests/include/EGLUtils.h b/opengl/tests/lib/include/EGLUtils.h
similarity index 100%
rename from opengl/tests/include/EGLUtils.h
rename to opengl/tests/lib/include/EGLUtils.h
diff --git a/opengl/tests/include/WindowSurface.h b/opengl/tests/lib/include/WindowSurface.h
similarity index 100%
rename from opengl/tests/include/WindowSurface.h
rename to opengl/tests/lib/include/WindowSurface.h
diff --git a/opengl/tests/include/glTestLib.h b/opengl/tests/lib/include/glTestLib.h
similarity index 100%
rename from opengl/tests/include/glTestLib.h
rename to opengl/tests/lib/include/glTestLib.h
diff --git a/opengl/tools/glgen2/registry/egl.xml b/opengl/tools/glgen2/registry/egl.xml
index af13395..c2d3494 100755
--- a/opengl/tools/glgen2/registry/egl.xml
+++ b/opengl/tools/glgen2/registry/egl.xml
@@ -191,6 +191,7 @@
<enum value="((EGLSync)0)" name="EGL_NO_SYNC"/>
<enum value="((EGLSyncKHR)0)" name="EGL_NO_SYNC_KHR" alias="EGL_NO_SYNC"/>
<enum value="((EGLSyncNV)0)" name="EGL_NO_SYNC_NV" alias="EGL_NO_SYNC"/>
+ <enum value="EGL_CAST(EGLConfig,0)" name="EGL_NO_CONFIG_KHR"/>
<enum value="10000" name="EGL_DISPLAY_SCALING"/>
<enum value="0xFFFFFFFFFFFFFFFF" name="EGL_FOREVER" type="ull"/>
<enum value="0xFFFFFFFFFFFFFFFF" name="EGL_FOREVER_KHR" type="ull" alias="EGL_FOREVER"/>
@@ -739,7 +740,10 @@
<enum value="50000" name="EGL_METADATA_SCALING_EXT"/>
<unused start="0x334B" end="0x334F"/>
<enum value="0x3350" name="EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT"/>
- <unused start="0x3351" end="0x339F"/>
+ <unused start="0x3351" end="0x3361"/>
+ <enum value="0x3362" name="EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT"/>
+ <enum value="0x3363" name="EGL_GL_COLORSPACE_DISPLAY_P3_EXT"/>
+ <unused start="0x3364" end="0x339F"/>
</enums>
<enums namespace="EGL" start="0x33A0" end="0x33AF" vendor="ANGLE" comment="Reserved for Shannon Woods (Bug 13175)">
@@ -1891,6 +1895,16 @@
<enum name="EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT"/>
</require>
</extension>
+ <extension name="EGL_EXT_gl_colorspace_display_p3_linear" supported="egl">
+ <require>
+ <enum name="EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT"/>
+ </require>
+ </extension>
+ <extension name="EGL_EXT_gl_colorspace_display_p3" supported="egl">
+ <require>
+ <enum name="EGL_GL_COLORSPACE_DISPLAY_P3_EXT"/>
+ </require>
+ </extension>
<extension name="EGL_EXT_image_dma_buf_import" supported="egl">
<require>
<enum name="EGL_LINUX_DMA_BUF_EXT"/>
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index d2f8995..50589b4 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -150,7 +150,8 @@
fd(fd), id(id), path(path), identifier(identifier),
classes(0), configuration(NULL), virtualKeyMap(NULL),
ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0),
- timestampOverrideSec(0), timestampOverrideUsec(0) {
+ timestampOverrideSec(0), timestampOverrideUsec(0), enabled(true),
+ isVirtual(fd < 0) {
memset(keyBitmask, 0, sizeof(keyBitmask));
memset(absBitmask, 0, sizeof(absBitmask));
memset(relBitmask, 0, sizeof(relBitmask));
@@ -173,6 +174,25 @@
}
}
+status_t EventHub::Device::enable() {
+ fd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK);
+ if(fd < 0) {
+ ALOGE("could not open %s, %s\n", path.string(), strerror(errno));
+ return -errno;
+ }
+ enabled = true;
+ return OK;
+}
+
+status_t EventHub::Device::disable() {
+ close();
+ enabled = false;
+ return OK;
+}
+
+bool EventHub::Device::hasValidFd() {
+ return !isVirtual && enabled;
+}
// --- EventHub ---
@@ -286,7 +306,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
+ if (device && device->hasValidFd() && test_bit(axis, device->absBitmask)) {
struct input_absinfo info;
if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
@@ -337,7 +357,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) {
+ if (device && device->hasValidFd() && test_bit(scanCode, device->keyBitmask)) {
uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
memset(keyState, 0, sizeof(keyState));
if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
@@ -352,7 +372,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) {
+ if (device && device->hasValidFd() && device->keyMap.haveKeyLayout()) {
Vector<int32_t> scanCodes;
device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
if (scanCodes.size() != 0) {
@@ -377,7 +397,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) {
+ if (device && device->hasValidFd() && test_bit(sw, device->swBitmask)) {
uint8_t swState[sizeof_bit_array(SW_MAX + 1)];
memset(swState, 0, sizeof(swState));
if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) {
@@ -395,7 +415,7 @@
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
+ if (device && device->hasValidFd() && test_bit(axis, device->absBitmask)) {
struct input_absinfo info;
if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
@@ -532,7 +552,7 @@
void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) {
int32_t sc;
- if (device && !device->isVirtual() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
+ if (device && device->hasValidFd() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
struct input_event ev;
ev.time.tv_sec = 0;
ev.time.tv_usec = 0;
@@ -636,7 +656,7 @@
void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual()) {
+ if (device && device->hasValidFd()) {
ff_effect effect;
memset(&effect, 0, sizeof(effect));
effect.type = FF_RUMBLE;
@@ -670,7 +690,7 @@
void EventHub::cancelVibrate(int32_t deviceId) {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual()) {
+ if (device && device->hasValidFd()) {
if (device->ffEffectPlaying) {
device->ffEffectPlaying = false;
@@ -1065,12 +1085,37 @@
AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE,
};
+status_t EventHub::registerDeviceForEpollLocked(Device* device) {
+ struct epoll_event eventItem;
+ memset(&eventItem, 0, sizeof(eventItem));
+ eventItem.events = EPOLLIN;
+ if (mUsingEpollWakeup) {
+ eventItem.events |= EPOLLWAKEUP;
+ }
+ eventItem.data.u32 = device->id;
+ if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, device->fd, &eventItem)) {
+ ALOGE("Could not add device fd to epoll instance. errno=%d", errno);
+ return -errno;
+ }
+ return OK;
+}
+
+status_t EventHub::unregisterDeviceFromEpollLocked(Device* device) {
+ if (device->hasValidFd()) {
+ if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) {
+ ALOGW("Could not remove device fd from epoll instance. errno=%d", errno);
+ return -errno;
+ }
+ }
+ return OK;
+}
+
status_t EventHub::openDeviceLocked(const char *devicePath) {
char buffer[80];
ALOGV("Opening device: %s", devicePath);
- int fd = open(devicePath, O_RDWR | O_CLOEXEC);
+ int fd = open(devicePath, O_RDWR | O_CLOEXEC | O_NONBLOCK);
if(fd < 0) {
ALOGE("could not open %s, %s\n", devicePath, strerror(errno));
return -1;
@@ -1135,13 +1180,6 @@
// Fill in the descriptor.
assignDescriptorLocked(identifier);
- // Make file descriptor non-blocking for use with poll().
- if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
- ALOGE("Error %d making device file descriptor non-blocking.", errno);
- close(fd);
- return -1;
- }
-
// Allocate device. (The device object takes ownership of the fd at this point.)
int32_t deviceId = mNextDeviceId++;
Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
@@ -1303,12 +1341,6 @@
break;
}
}
-
- // Disable kernel key repeat since we handle it ourselves
- unsigned int repeatRate[] = {0,0};
- if (ioctl(fd, EVIOCSREP, repeatRate)) {
- ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno));
- }
}
// If the device isn't recognized as something we handle, don't monitor it.
@@ -1332,23 +1364,41 @@
if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_DPAD)
&& device->classes & INPUT_DEVICE_CLASS_GAMEPAD) {
device->controllerNumber = getNextControllerNumberLocked(device);
- setLedForController(device);
+ setLedForControllerLocked(device);
}
- // Register with epoll.
- struct epoll_event eventItem;
- memset(&eventItem, 0, sizeof(eventItem));
- eventItem.events = EPOLLIN;
- if (mUsingEpollWakeup) {
- eventItem.events |= EPOLLWAKEUP;
- }
- eventItem.data.u32 = deviceId;
- if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
- ALOGE("Could not add device fd to epoll instance. errno=%d", errno);
+
+ if (registerDeviceForEpollLocked(device) != OK) {
delete device;
return -1;
}
+ configureFd(device);
+
+ ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
+ "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
+ deviceId, fd, devicePath, device->identifier.name.string(),
+ device->classes,
+ device->configurationFile.string(),
+ device->keyMap.keyLayoutFile.string(),
+ device->keyMap.keyCharacterMapFile.string(),
+ toString(mBuiltInKeyboardId == deviceId));
+
+ addDeviceLocked(device);
+ return OK;
+}
+
+void EventHub::configureFd(Device* device) {
+ // Set fd parameters with ioctl, such as key repeat, suspend block, and clock type
+ if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+ // Disable kernel key repeat since we handle it ourselves
+ unsigned int repeatRate[] = {0, 0};
+ if (ioctl(device->fd, EVIOCSREP, repeatRate)) {
+ ALOGW("Unable to disable kernel key repeat for %s: %s",
+ device->path.string(), strerror(errno));
+ }
+ }
+
String8 wakeMechanism("EPOLLWAKEUP");
if (!mUsingEpollWakeup) {
#ifndef EVIOCSSUSPENDBLOCK
@@ -1357,44 +1407,67 @@
// this feature, we need to be prepared to define the ioctl ourselves.
#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
#endif
- if (ioctl(fd, EVIOCSSUSPENDBLOCK, 1)) {
+ if (ioctl(device->fd, EVIOCSSUSPENDBLOCK, 1)) {
wakeMechanism = "<none>";
} else {
wakeMechanism = "EVIOCSSUSPENDBLOCK";
}
}
-
// Tell the kernel that we want to use the monotonic clock for reporting timestamps
// associated with input events. This is important because the input system
// uses the timestamps extensively and assumes they were recorded using the monotonic
// clock.
- //
- // In older kernel, before Linux 3.4, there was no way to tell the kernel which
- // clock to use to input event timestamps. The standard kernel behavior was to
- // record a real time timestamp, which isn't what we want. Android kernels therefore
- // contained a patch to the evdev_event() function in drivers/input/evdev.c to
- // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic
- // clock to be used instead of the real time clock.
- //
- // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock.
- // Therefore, we no longer require the Android-specific kernel patch described above
- // as long as we make sure to set select the monotonic clock. We do that here.
int clockId = CLOCK_MONOTONIC;
- bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
+ bool usingClockIoctl = !ioctl(device->fd, EVIOCSCLOCKID, &clockId);
+ ALOGI("wakeMechanism=%s, usingClockIoctl=%s", wakeMechanism.string(),
+ toString(usingClockIoctl));
+}
- ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
- "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
- "wakeMechanism=%s, usingClockIoctl=%s",
- deviceId, fd, devicePath, device->identifier.name.string(),
- device->classes,
- device->configurationFile.string(),
- device->keyMap.keyLayoutFile.string(),
- device->keyMap.keyCharacterMapFile.string(),
- toString(mBuiltInKeyboardId == deviceId),
- wakeMechanism.string(), toString(usingClockIoctl));
+bool EventHub::isDeviceEnabled(int32_t deviceId) {
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device == NULL) {
+ ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return false;
+ }
+ return device->enabled;
+}
- addDeviceLocked(device);
- return 0;
+status_t EventHub::enableDevice(int32_t deviceId) {
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device == NULL) {
+ ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (device->enabled) {
+ ALOGW("Duplicate call to %s, input device %" PRId32 " already enabled", __func__, deviceId);
+ return OK;
+ }
+ status_t result = device->enable();
+ if (result != OK) {
+ ALOGE("Failed to enable device %" PRId32, deviceId);
+ return result;
+ }
+
+ configureFd(device);
+
+ return registerDeviceForEpollLocked(device);
+}
+
+status_t EventHub::disableDevice(int32_t deviceId) {
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device == NULL) {
+ ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (!device->enabled) {
+ ALOGW("Duplicate call to %s, input device already disabled", __func__);
+ return OK;
+ }
+ unregisterDeviceFromEpollLocked(device);
+ return device->disable();
}
void EventHub::createVirtualKeyboardLocked() {
@@ -1490,7 +1563,7 @@
mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
}
-void EventHub::setLedForController(Device* device) {
+void EventHub::setLedForControllerLocked(Device* device) {
for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1);
}
@@ -1500,7 +1573,7 @@
if (!device->keyMap.haveKeyLayout()) {
return false;
}
-
+
Vector<int32_t> scanCodes;
device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
const size_t N = scanCodes.size();
@@ -1510,7 +1583,7 @@
return true;
}
}
-
+
return false;
}
@@ -1556,11 +1629,7 @@
mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
}
- if (!device->isVirtual()) {
- if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) {
- ALOGW("Could not remove device fd from epoll instance. errno=%d", errno);
- }
- }
+ unregisterDeviceFromEpollLocked(device);
releaseControllerNumberLocked(device);
@@ -1691,6 +1760,7 @@
}
dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
+ dump.appendFormat(INDENT3 "Enabled: %s\n", toString(device->enabled));
dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
dump.appendFormat(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 6869253..727b73a 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -25,9 +25,8 @@
#include <input/KeyCharacterMap.h>
#include <input/VirtualKeyMap.h>
#include <utils/String8.h>
-#include <utils/threads.h>
+#include <utils/Mutex.h>
#include <utils/Log.h>
-#include <utils/threads.h>
#include <utils/List.h>
#include <utils/Errors.h>
#include <utils/PropertyMap.h>
@@ -267,6 +266,15 @@
/* Called by the heatbeat to ensures that the reader has not deadlocked. */
virtual void monitor() = 0;
+
+ /* Return true if the device is enabled. */
+ virtual bool isDeviceEnabled(int32_t deviceId) = 0;
+
+ /* Enable an input device */
+ virtual status_t enableDevice(int32_t deviceId) = 0;
+
+ /* Disable an input device. Closes file descriptor to that device. */
+ virtual status_t disableDevice(int32_t deviceId) = 0;
};
class EventHub : public EventHubInterface
@@ -335,7 +343,7 @@
struct Device {
Device* next;
- int fd; // may be -1 if device is virtual
+ int fd; // may be -1 if device is closed
const int32_t id;
const String8 path;
const InputDeviceIdentifier identifier;
@@ -371,7 +379,11 @@
void close();
- inline bool isVirtual() const { return fd < 0; }
+ bool enabled; // initially true
+ status_t enable();
+ status_t disable();
+ bool hasValidFd();
+ const bool isVirtual; // set if fd < 0 is passed to constructor
const sp<KeyCharacterMap>& getKeyCharacterMap() const {
if (combinedKeyMap != NULL) {
@@ -390,6 +402,14 @@
void closeDeviceLocked(Device* device);
void closeAllDevicesLocked();
+ void configureFd(Device* device);
+
+ bool isDeviceEnabled(int32_t deviceId);
+ status_t enableDevice(int32_t deviceId);
+ status_t disableDevice(int32_t deviceId);
+ status_t registerDeviceForEpollLocked(Device* device);
+ status_t unregisterDeviceFromEpollLocked(Device* device);
+
status_t scanDirLocked(const char *dirname);
void scanDevicesLocked();
status_t readNotifyLocked();
@@ -409,7 +429,7 @@
int32_t getNextControllerNumberLocked(Device* device);
void releaseControllerNumberLocked(Device* device);
- void setLedForController(Device* device);
+ void setLedForControllerLocked(Device* device);
status_t mapLed(Device* device, int32_t led, int32_t* outScanCode) const;
void setLedStateLocked(Device* device, int32_t led, bool on);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 2705e13..8af9038 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -788,6 +788,18 @@
}
}
+bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
+ AutoMutex _l(mLock);
+
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ return device->isEnabled();
+ }
+ ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
+ return false;
+}
+
void InputReader::dump(String8& dump) {
AutoMutex _l(mLock);
@@ -961,6 +973,26 @@
mMappers.clear();
}
+bool InputDevice::isEnabled() {
+ return getEventHub()->isDeviceEnabled(mId);
+}
+
+void InputDevice::setEnabled(bool enabled, nsecs_t when) {
+ if (isEnabled() == enabled) {
+ return;
+ }
+
+ if (enabled) {
+ getEventHub()->enableDevice(mId);
+ reset(when);
+ } else {
+ reset(when);
+ getEventHub()->disableDevice(mId);
+ }
+ // Must change generation to flag this device as changed
+ bumpGeneration();
+}
+
void InputDevice::dump(String8& dump) {
InputDeviceInfo deviceInfo;
getDeviceInfo(& deviceInfo);
@@ -1032,6 +1064,12 @@
}
}
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
+ ssize_t index = config->disabledDevices.indexOf(mId);
+ bool enabled = index < 0;
+ setEnabled(enabled, when);
+ }
+
size_t numMappers = mMappers.size();
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 3171526..647f271 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -26,11 +26,14 @@
#include <input/VelocityTracker.h>
#include <ui/DisplayInfo.h>
#include <utils/KeyedVector.h>
-#include <utils/threads.h>
+#include <utils/Condition.h>
+#include <utils/Thread.h>
+#include <utils/Mutex.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/BitSet.h>
+#include <utils/SortedVector.h>
#include <stddef.h>
#include <unistd.h>
@@ -147,6 +150,9 @@
// The pointer capture mode has changed.
CHANGE_POINTER_CAPTURE = 1 << 8,
+ // The set of disabled input devices (disabledDevices) has changed.
+ CHANGE_ENABLED_STATE = 1 << 9,
+
// All devices must be reopened.
CHANGE_MUST_REOPEN = 1 << 31,
};
@@ -237,6 +243,9 @@
// True if pointer capture is enabled.
bool pointerCapture;
+ // The set of currently disabled input devices.
+ SortedVector<int32_t> disabledDevices;
+
InputReaderConfiguration() :
virtualKeyQuietTime(0),
pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
@@ -344,6 +353,9 @@
/* Called by the heatbeat to ensures that the reader has not deadlocked. */
virtual void monitor() = 0;
+ /* Returns true if the input device is enabled. */
+ virtual bool isInputDeviceEnabled(int32_t deviceId) = 0;
+
/* Runs a single iteration of the processing loop.
* Nominally reads and processes one incoming message from the EventHub.
*
@@ -463,6 +475,8 @@
virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices);
+ virtual bool isInputDeviceEnabled(int32_t deviceId);
+
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t scanCode);
virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
@@ -608,6 +622,9 @@
inline bool isIgnored() { return mMappers.isEmpty(); }
+ bool isEnabled();
+ void setEnabled(bool enabled, nsecs_t when);
+
void dump(String8& dump);
void addMapper(InputMapper* mapper);
void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 2e0bcd1..7082fe1 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -16,6 +16,7 @@
#include "../InputReader.h"
+#include <inttypes.h>
#include <utils/List.h>
#include <gtest/gtest.h>
#include <math.h>
@@ -161,6 +162,22 @@
mConfig.excludedDeviceNames.push(deviceName);
}
+ void addDisabledDevice(int32_t deviceId) {
+ ssize_t index = mConfig.disabledDevices.indexOf(deviceId);
+ bool currentlyEnabled = index < 0;
+ if (currentlyEnabled) {
+ mConfig.disabledDevices.add(deviceId);
+ }
+ }
+
+ void removeDisabledDevice(int32_t deviceId) {
+ ssize_t index = mConfig.disabledDevices.indexOf(deviceId);
+ bool currentlyEnabled = index < 0;
+ if (!currentlyEnabled) {
+ mConfig.disabledDevices.remove(deviceId);
+ }
+ }
+
void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
mPointerControllers.add(deviceId, controller);
}
@@ -236,6 +253,11 @@
mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
}
+ void assertNotifyConfigurationChangedWasNotCalled() {
+ ASSERT_TRUE(mNotifyConfigurationChangedArgsQueue.empty())
+ << "Expected notifyConfigurationChanged() to not have been called.";
+ }
+
void assertNotifyDeviceResetWasCalled(
NotifyDeviceResetArgs* outEventArgs = NULL) {
ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
@@ -246,6 +268,11 @@
mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
}
+ void assertNotifyDeviceResetWasNotCalled() {
+ ASSERT_TRUE(mNotifyDeviceResetArgsQueue.empty())
+ << "Expected notifyDeviceReset() to not have been called.";
+ }
+
void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
<< "Expected notifyKey() to have been called.";
@@ -328,9 +355,20 @@
KeyedVector<int32_t, KeyInfo> keysByUsageCode;
KeyedVector<int32_t, bool> leds;
Vector<VirtualKeyDefinition> virtualKeys;
+ bool enabled;
+
+ status_t enable() {
+ enabled = true;
+ return OK;
+ }
+
+ status_t disable() {
+ enabled = false;
+ return OK;
+ }
explicit Device(uint32_t classes) :
- classes(classes) {
+ classes(classes), enabled(true) {
}
};
@@ -363,6 +401,43 @@
enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
}
+ bool isDeviceEnabled(int32_t deviceId) {
+ Device* device = getDevice(deviceId);
+ if (device == NULL) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return false;
+ }
+ return device->enabled;
+ }
+
+ status_t enableDevice(int32_t deviceId) {
+ status_t result;
+ Device* device = getDevice(deviceId);
+ if (device == NULL) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (device->enabled) {
+ ALOGW("Duplicate call to %s, device %" PRId32 " already enabled", __func__, deviceId);
+ return OK;
+ }
+ result = device->enable();
+ return result;
+ }
+
+ status_t disableDevice(int32_t deviceId) {
+ Device* device = getDevice(deviceId);
+ if (device == NULL) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (!device->enabled) {
+ ALOGW("Duplicate call to %s, device %" PRId32 " already disabled", __func__, deviceId);
+ return OK;
+ }
+ return device->disable();
+ }
+
void finishDeviceScan() {
enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
}
@@ -1020,6 +1095,20 @@
mFakeEventHub->assertQueueIsEmpty();
}
+ void disableDevice(int32_t deviceId, InputDevice* device) {
+ mFakePolicy->addDisabledDevice(deviceId);
+ configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE, device);
+ }
+
+ void enableDevice(int32_t deviceId, InputDevice* device) {
+ mFakePolicy->removeDisabledDevice(deviceId);
+ configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE, device);
+ }
+
+ void configureDevice(uint32_t changes, InputDevice* device) {
+ device->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
+ }
+
FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
const String8& name, uint32_t classes, uint32_t sources,
const PropertyMap* configuration) {
@@ -1058,6 +1147,46 @@
ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
}
+TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
+ constexpr int32_t deviceId = 1;
+ constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
+ InputDevice* device = mReader->newDevice(deviceId, 0, String8("fake"), deviceClass);
+ // Must add at least one mapper or the device will be ignored!
+ FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
+ device->addMapper(mapper);
+ mReader->setNextDevice(device);
+ addDevice(deviceId, String8("fake"), deviceClass, NULL);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(NULL));
+
+ NotifyDeviceResetArgs resetArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(deviceId, resetArgs.deviceId);
+
+ ASSERT_EQ(device->isEnabled(), true);
+ disableDevice(deviceId, device);
+ mReader->loopOnce();
+
+ mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(deviceId, resetArgs.deviceId);
+ ASSERT_EQ(device->isEnabled(), false);
+
+ disableDevice(deviceId, device);
+ mReader->loopOnce();
+ mFakeListener->assertNotifyDeviceResetWasNotCalled();
+ mFakeListener->assertNotifyConfigurationChangedWasNotCalled();
+ ASSERT_EQ(device->isEnabled(), false);
+
+ enableDevice(deviceId, device);
+ mReader->loopOnce();
+ mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs);
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(deviceId, resetArgs.deviceId);
+ ASSERT_EQ(device->isEnabled(), true);
+}
+
TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
FakeInputMapper* mapper = NULL;
ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
@@ -1255,6 +1384,10 @@
ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
}
+TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsTrue) {
+ ASSERT_EQ(mDevice->isEnabled(), true);
+}
+
TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
// Configuration.
InputReaderConfiguration config;
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 8c2300e..8d381b1 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -1,3 +1,73 @@
subdirs = [
"hidl"
]
+cc_library_shared {
+ name: "libsensorservice",
+
+ srcs: [
+ "BatteryService.cpp",
+ "CorrectedGyroSensor.cpp",
+ "Fusion.cpp",
+ "GravitySensor.cpp",
+ "LinearAccelerationSensor.cpp",
+ "OrientationSensor.cpp",
+ "RecentEventLogger.cpp",
+ "RotationVectorSensor.cpp",
+ "SensorDevice.cpp",
+ "SensorDirectConnection.cpp",
+ "SensorEventConnection.cpp",
+ "SensorFusion.cpp",
+ "SensorInterface.cpp",
+ "SensorList.cpp",
+ "SensorRecord.cpp",
+ "SensorService.cpp",
+ "SensorServiceUtils.cpp",
+ ],
+
+ cflags: [
+ "-DLOG_TAG=\"SensorService\"",
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ "-fvisibility=hidden"
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "libhardware",
+ "libhardware_legacy",
+ "libutils",
+ "liblog",
+ "libbinder",
+ "libsensor",
+ "libcrypto",
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "android.hardware.sensors@1.0",
+ ],
+
+ static_libs: ["android.hardware.sensors@1.0-convert"],
+
+ // our public headers depend on libsensor
+ export_shared_lib_headers: ["libsensor"],
+}
+
+cc_binary {
+ name: "sensorservice",
+
+ srcs: ["main_sensorservice.cpp"],
+
+ shared_libs: [
+ "libsensorservice",
+ "libbinder",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
deleted file mode 100644
index cfb7231..0000000
--- a/services/sensorservice/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- BatteryService.cpp \
- CorrectedGyroSensor.cpp \
- Fusion.cpp \
- GravitySensor.cpp \
- LinearAccelerationSensor.cpp \
- OrientationSensor.cpp \
- RecentEventLogger.cpp \
- RotationVectorSensor.cpp \
- SensorDevice.cpp \
- SensorDirectConnection.cpp \
- SensorEventConnection.cpp \
- SensorFusion.cpp \
- SensorInterface.cpp \
- SensorList.cpp \
- SensorRecord.cpp \
- SensorService.cpp \
- SensorServiceUtils.cpp \
-
-LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
-
-LOCAL_CFLAGS += -Wall -Werror -Wextra
-
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libhardware \
- libhardware_legacy \
- libutils \
- liblog \
- libbinder \
- libsensor \
- libcrypto \
- libbase \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- android.hardware.sensors@1.0
-
-LOCAL_STATIC_LIBRARIES := \
- android.hardware.sensors@1.0-convert
-
-# our public headers depend on libsensor
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
- libsensor \
-
-LOCAL_MODULE:= libsensorservice
-
-include $(BUILD_SHARED_LIBRARY)
-
-#####################################################################
-# build executable
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- main_sensorservice.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libsensorservice \
- libbinder \
- libutils
-
-LOCAL_CFLAGS := -Wall -Werror -Wextra
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= sensorservice
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index d60768c..b5baba8 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -394,6 +394,7 @@
}
} else if (!mSensors.hasAnySensor()) {
result.append("No Sensors on the device\n");
+ result.append("devInitCheck : %d\n", SensorDevice::getInstance().initCheck());
} else {
// Default dump the sensor list and debugging information.
//
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 7bb20ba..0071851 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -54,11 +54,7 @@
LOCAL_SRC_FILES += \
SurfaceFlinger.cpp \
DisplayHardware/HWComposer.cpp
- ifeq ($(TARGET_USES_HWC2ON1ADAPTER), true)
- LOCAL_CFLAGS += -DBYPASS_IHWC
- endif
else
- LOCAL_CFLAGS += -DBYPASS_IHWC
LOCAL_SRC_FILES += \
SurfaceFlinger_hwc1.cpp \
DisplayHardware/HWComposer_hwc1.cpp
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b5ffc60..4d0c085 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -121,7 +121,8 @@
ANativeWindow* const window = mNativeWindow.get();
#ifdef USE_HWC2
- mActiveColorMode = static_cast<android_color_mode_t>(-1);
+ // Set defaultColorMode to SRGB if this device supports wide-color
+ mActiveColorMode = (supportWideColor) ? HAL_COLOR_MODE_SRGB : HAL_COLOR_MODE_NATIVE;
mDisplayHasWideColor = supportWideColor;
#else
(void) supportWideColor;
@@ -610,23 +611,25 @@
void DisplayDevice::dump(String8& result) const {
const Transform& tr(mGlobalTransform);
- result.appendFormat(
- "+ DisplayDevice: %s\n"
- " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
- "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
- " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
- "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
- mDisplayName.string(), mType, mHwcDisplayId,
- mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
- mOrientation, tr.getType(), getPageFlipCount(),
- mIsSecure, mPowerMode, mActiveConfig,
- mVisibleLayersSortedByZ.size(),
- mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
- mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
- mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
- tr[0][0], tr[1][0], tr[2][0],
- tr[0][1], tr[1][1], tr[2][1],
- tr[0][2], tr[1][2], tr[2][2]);
+ EGLint redSize, greenSize, blueSize, alphaSize;
+ eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize);
+ eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize);
+ eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize);
+ eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize);
+ result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
+ result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
+ "(%d:%d:%d:%d), orient=%2d (type=%08x), "
+ "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
+ mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight,
+ mNativeWindow.get(), redSize, greenSize, blueSize, alphaSize, mOrientation,
+ tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
+ mVisibleLayersSortedByZ.size());
+ result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
+ "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
+ mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
+ mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left,
+ mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0],
+ tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
String8 surfaceDump;
mDisplaySurface->dumpAsString(surfaceDump);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 8270c39..1ac203b 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -88,55 +88,8 @@
// Device methods
-#ifdef BYPASS_IHWC
-Device::Device(hwc2_device_t* device)
- : mHwcDevice(device),
- mCreateVirtualDisplay(nullptr),
- mDestroyVirtualDisplay(nullptr),
- mDump(nullptr),
- mGetMaxVirtualDisplayCount(nullptr),
- mRegisterCallback(nullptr),
- mAcceptDisplayChanges(nullptr),
- mCreateLayer(nullptr),
- mDestroyLayer(nullptr),
- mGetActiveConfig(nullptr),
- mGetChangedCompositionTypes(nullptr),
- mGetColorModes(nullptr),
- mGetDisplayAttribute(nullptr),
- mGetDisplayConfigs(nullptr),
- mGetDisplayName(nullptr),
- mGetDisplayRequests(nullptr),
- mGetDisplayType(nullptr),
- mGetDozeSupport(nullptr),
- mGetHdrCapabilities(nullptr),
- mGetReleaseFences(nullptr),
- mPresentDisplay(nullptr),
- mSetActiveConfig(nullptr),
- mSetClientTarget(nullptr),
- mSetColorMode(nullptr),
- mSetColorTransform(nullptr),
- mSetOutputBuffer(nullptr),
- mSetPowerMode(nullptr),
- mSetVsyncEnabled(nullptr),
- mValidateDisplay(nullptr),
- mSetCursorPosition(nullptr),
- mSetLayerBuffer(nullptr),
- mSetLayerSurfaceDamage(nullptr),
- mSetLayerBlendMode(nullptr),
- mSetLayerColor(nullptr),
- mSetLayerCompositionType(nullptr),
- mSetLayerDataspace(nullptr),
- mSetLayerDisplayFrame(nullptr),
- mSetLayerPlaneAlpha(nullptr),
- mSetLayerSidebandStream(nullptr),
- mSetLayerSourceCrop(nullptr),
- mSetLayerTransform(nullptr),
- mSetLayerVisibleRegion(nullptr),
- mSetLayerZOrder(nullptr),
-#else
Device::Device(bool useVrComposer)
: mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
-#endif // BYPASS_IHWC
mCapabilities(),
mDisplays(),
mHotplug(),
@@ -147,18 +100,11 @@
mPendingVsyncs()
{
loadCapabilities();
- loadFunctionPointers();
registerCallbacks();
}
Device::~Device()
{
-#ifdef BYPASS_IHWC
- if (mHwcDevice == nullptr) {
- return;
- }
-#endif
-
for (auto element : mDisplays) {
auto display = element.second.lock();
if (!display) {
@@ -185,36 +131,18 @@
}
}
}
-
-#ifdef BYPASS_IHWC
- hwc2_close(mHwcDevice);
-#endif
}
// Required by HWC2 device
std::string Device::dump() const
{
-#ifdef BYPASS_IHWC
- uint32_t numBytes = 0;
- mDump(mHwcDevice, &numBytes, nullptr);
-
- std::vector<char> buffer(numBytes);
- mDump(mHwcDevice, &numBytes, buffer.data());
-
- return std::string(buffer.data(), buffer.size());
-#else
return mComposer->dumpDebugInfo();
-#endif
}
uint32_t Device::getMaxVirtualDisplayCount() const
{
-#ifdef BYPASS_IHWC
- return mGetMaxVirtualDisplayCount(mHwcDevice);
-#else
return mComposer->getMaxVirtualDisplayCount();
-#endif
}
Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
@@ -223,15 +151,9 @@
ALOGI("Creating virtual display");
hwc2_display_t displayId = 0;
-#ifdef BYPASS_IHWC
- int32_t intFormat = static_cast<int32_t>(*format);
- int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
- &intFormat, &displayId);
-#else
auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
auto intError = mComposer->createVirtualDisplay(width, height,
&intFormat, &displayId);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -285,9 +207,7 @@
{
if (connected == Connection::Connected) {
if (!display->isConnected()) {
-#ifndef BYPASS_IHWC
mComposer->setClientTargetSlotCount(display->getId());
-#endif
display->loadConfigs();
display->setConnected(true);
}
@@ -345,21 +265,10 @@
{
static_assert(sizeof(Capability) == sizeof(int32_t),
"Capability size has changed");
-#ifdef BYPASS_IHWC
- uint32_t numCapabilities = 0;
- mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
- std::vector<Capability> capabilities(numCapabilities);
- auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
- mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
- for (auto capability : capabilities) {
- mCapabilities.emplace(capability);
- }
-#else
auto capabilities = mComposer->getCapabilities();
for (auto capability : capabilities) {
mCapabilities.emplace(static_cast<Capability>(capability));
}
-#endif
}
bool Device::hasCapability(HWC2::Capability capability) const
@@ -368,105 +277,6 @@
capability) != mCapabilities.cend();
}
-void Device::loadFunctionPointers()
-{
-#ifdef BYPASS_IHWC
- // For all of these early returns, we log an error message inside
- // loadFunctionPointer specifying which function failed to load
-
- // Display function pointers
- if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
- mCreateVirtualDisplay)) return;
- if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
- mDestroyVirtualDisplay)) return;
- if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
- mGetMaxVirtualDisplayCount)) return;
- if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
- mRegisterCallback)) return;
-
- // Device function pointers
- if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
- mAcceptDisplayChanges)) return;
- if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
- mCreateLayer)) return;
- if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
- mDestroyLayer)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
- mGetActiveConfig)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
- mGetChangedCompositionTypes)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
- mGetColorModes)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
- mGetDisplayAttribute)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
- mGetDisplayConfigs)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
- mGetDisplayName)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
- mGetDisplayRequests)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
- mGetDisplayType)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
- mGetDozeSupport)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
- mGetHdrCapabilities)) return;
- if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
- mGetReleaseFences)) return;
- if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
- mPresentDisplay)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
- mSetActiveConfig)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
- mSetClientTarget)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
- mSetColorMode)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
- mSetColorTransform)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
- mSetOutputBuffer)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
- mSetPowerMode)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
- mSetVsyncEnabled)) return;
- if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
- mValidateDisplay)) return;
-
- // Layer function pointers
- if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
- mSetCursorPosition)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
- mSetLayerBuffer)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
- mSetLayerSurfaceDamage)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
- mSetLayerBlendMode)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
- mSetLayerColor)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
- mSetLayerCompositionType)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
- mSetLayerDataspace)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
- mSetLayerDisplayFrame)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
- mSetLayerPlaneAlpha)) return;
- if (hasCapability(Capability::SidebandStream)) {
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
- mSetLayerSidebandStream)) return;
- }
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
- mSetLayerSourceCrop)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
- mSetLayerTransform)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
- mSetLayerVisibleRegion)) return;
- if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
- mSetLayerZOrder)) return;
-#endif // BYPASS_IHWC
-}
-
namespace {
class ComposerCallback : public Hwc2::IComposerCallback {
public:
@@ -498,14 +308,8 @@
void Device::registerCallbacks()
{
-#ifdef BYPASS_IHWC
- registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
- registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
- registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
-#else
sp<ComposerCallback> callback = new ComposerCallback(this);
mComposer->registerCallback(callback);
-#endif
}
@@ -514,11 +318,7 @@
void Device::destroyVirtualDisplay(hwc2_display_t display)
{
ALOGI("Destroying virtual display");
-#ifdef BYPASS_IHWC
- int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
-#else
auto intError = mComposer->destroyVirtualDisplay(display);
-#endif
auto error = static_cast<Error>(intError);
ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
" %s (%d)", display, to_string(error).c_str(), intError);
@@ -535,13 +335,8 @@
{
ALOGV("Created display %" PRIu64, id);
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
- reinterpret_cast<int32_t *>(&mType));
-#else
auto intError = mDevice.mComposer->getDisplayType(mId,
reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
@@ -588,22 +383,14 @@
Error Display::acceptChanges()
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
-#else
auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
-#endif
return static_cast<Error>(intError);
}
Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
{
hwc2_layer_t layerId = 0;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
-#else
auto intError = mDevice.mComposer->createLayer(mId, &layerId);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -620,12 +407,7 @@
{
ALOGV("[%" PRIu64 "] getActiveConfig", mId);
hwc2_config_t configId = 0;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
- &configId);
-#else
auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
@@ -650,27 +432,12 @@
Error Display::getChangedCompositionTypes(
std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
{
-#ifdef BYPASS_IHWC
- uint32_t numElements = 0;
- int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
- mId, &numElements, nullptr, nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<hwc2_layer_t> layerIds(numElements);
- std::vector<int32_t> types(numElements);
- intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
- &numElements, layerIds.data(), types.data());
-#else
std::vector<Hwc2::Layer> layerIds;
std::vector<Hwc2::IComposerClient::Composition> types;
auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
&layerIds, &types);
uint32_t numElements = layerIds.size();
auto error = static_cast<Error>(intError);
-#endif
error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -696,25 +463,10 @@
Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
{
-#ifdef BYPASS_IHWC
- uint32_t numModes = 0;
- int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
- &numModes, nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<int32_t> modes(numModes);
- intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
- modes.data());
- error = static_cast<Error>(intError);
-#else
std::vector<Hwc2::ColorMode> modes;
auto intError = mDevice.mComposer->getColorModes(mId, &modes);
uint32_t numModes = modes.size();
auto error = static_cast<Error>(intError);
-#endif
if (error != Error::None) {
return error;
}
@@ -737,52 +489,14 @@
Error Display::getName(std::string* outName) const
{
-#ifdef BYPASS_IHWC
- uint32_t size;
- int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
- nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<char> rawName(size);
- intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
- rawName.data());
- error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- *outName = std::string(rawName.cbegin(), rawName.cend());
- return Error::None;
-#else
auto intError = mDevice.mComposer->getDisplayName(mId, outName);
return static_cast<Error>(intError);
-#endif
}
Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
outLayerRequests)
{
-#ifdef BYPASS_IHWC
- int32_t intDisplayRequests = 0;
- uint32_t numElements = 0;
- int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
- &intDisplayRequests, &numElements, nullptr, nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<hwc2_layer_t> layerIds(numElements);
- std::vector<int32_t> layerRequests(numElements);
- intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
- &intDisplayRequests, &numElements, layerIds.data(),
- layerRequests.data());
- error = static_cast<Error>(intError);
-#else
uint32_t intDisplayRequests;
std::vector<Hwc2::Layer> layerIds;
std::vector<uint32_t> layerRequests;
@@ -790,7 +504,6 @@
&intDisplayRequests, &layerIds, &layerRequests);
uint32_t numElements = layerIds.size();
auto error = static_cast<Error>(intError);
-#endif
if (error != Error::None) {
return error;
}
@@ -821,14 +534,8 @@
Error Display::supportsDoze(bool* outSupport) const
{
-#ifdef BYPASS_IHWC
- int32_t intSupport = 0;
- int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
- &intSupport);
-#else
bool intSupport = false;
auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -844,20 +551,6 @@
float maxLuminance = -1.0f;
float maxAverageLuminance = -1.0f;
float minLuminance = -1.0f;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
- &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
- &minLuminance);
- auto error = static_cast<HWC2::Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<int32_t> types(numTypes);
- intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
- types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
- error = static_cast<HWC2::Error>(intError);
-#else
std::vector<Hwc2::Hdr> intTypes;
auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
&maxLuminance, &maxAverageLuminance, &minLuminance);
@@ -868,7 +561,6 @@
types.push_back(static_cast<int32_t>(type));
}
numTypes = types.size();
-#endif
if (error != Error::None) {
return error;
}
@@ -881,28 +573,12 @@
Error Display::getReleaseFences(
std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
{
-#ifdef BYPASS_IHWC
- uint32_t numElements = 0;
- int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
- &numElements, nullptr, nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- std::vector<hwc2_layer_t> layerIds(numElements);
- std::vector<int32_t> fenceFds(numElements);
- intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
- layerIds.data(), fenceFds.data());
- error = static_cast<Error>(intError);
-#else
std::vector<Hwc2::Layer> layerIds;
std::vector<int> fenceFds;
auto intError = mDevice.mComposer->getReleaseFences(mId,
&layerIds, &fenceFds);
auto error = static_cast<Error>(intError);
uint32_t numElements = layerIds.size();
-#endif
if (error != Error::None) {
return error;
}
@@ -928,12 +604,7 @@
Error Display::present(sp<Fence>* outPresentFence)
{
int32_t presentFenceFd = -1;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
- &presentFenceFd);
-#else
auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -951,12 +622,7 @@
config->getDisplayId(), mId);
return Error::BadConfig;
}
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
- config->getId());
-#else
auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
-#endif
return static_cast<Error>(intError);
}
@@ -965,44 +631,24 @@
{
// TODO: Properly encode client target surface damage
int32_t fenceFd = acquireFence->dup();
-#ifdef BYPASS_IHWC
- (void) slot;
- buffer_handle_t handle = nullptr;
- if (target.get() && target->getNativeBuffer()) {
- handle = target->getNativeBuffer()->handle;
- }
-
- int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, handle,
- fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
-#else
auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
std::vector<Hwc2::IComposerClient::Rect>());
-#endif
return static_cast<Error>(intError);
}
Error Display::setColorMode(android_color_mode_t mode)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
-#else
auto intError = mDevice.mComposer->setColorMode(mId,
static_cast<Hwc2::ColorMode>(mode));
-#endif
return static_cast<Error>(intError);
}
Error Display::setColorTransform(const android::mat4& matrix,
android_color_transform_t hint)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
- matrix.asArray(), static_cast<int32_t>(hint));
-#else
auto intError = mDevice.mComposer->setColorTransform(mId,
matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
-#endif
return static_cast<Error>(intError);
}
@@ -1011,38 +657,22 @@
{
int32_t fenceFd = releaseFence->dup();
auto handle = buffer->getNativeBuffer()->handle;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
- fenceFd);
-#else
auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
-#endif
close(fenceFd);
return static_cast<Error>(intError);
}
Error Display::setPowerMode(PowerMode mode)
{
-#ifdef BYPASS_IHWC
- auto intMode = static_cast<int32_t>(mode);
- int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
-#else
auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
-#endif
return static_cast<Error>(intError);
}
Error Display::setVsyncEnabled(Vsync enabled)
{
-#ifdef BYPASS_IHWC
- auto intEnabled = static_cast<int32_t>(enabled);
- int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
- intEnabled);
-#else
auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
-#endif
return static_cast<Error>(intError);
}
@@ -1050,13 +680,8 @@
{
uint32_t numTypes = 0;
uint32_t numRequests = 0;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
- &numTypes, &numRequests);
-#else
auto intError = mDevice.mComposer->validateDisplay(mId,
&numTypes, &numRequests);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None && error != Error::HasChanges) {
return error;
@@ -1072,14 +697,9 @@
int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
{
int32_t value = 0;
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
- configId, static_cast<int32_t>(attribute), &value);
-#else
auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
static_cast<Hwc2::IComposerClient::Attribute>(attribute),
&value);
-#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
@@ -1108,26 +728,9 @@
{
ALOGV("[%" PRIu64 "] loadConfigs", mId);
-#ifdef BYPASS_IHWC
- uint32_t numConfigs = 0;
- int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
- &numConfigs, nullptr);
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
- to_string(error).c_str(), intError);
- return;
- }
-
- std::vector<hwc2_config_t> configIds(numConfigs);
- intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
- configIds.data());
- error = static_cast<Error>(intError);
-#else
std::vector<Hwc2::Config> configIds;
auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
auto error = static_cast<Error>(intError);
-#endif
if (error != Error::None) {
ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
to_string(error).c_str(), intError);
@@ -1143,11 +746,7 @@
void Display::destroyLayer(hwc2_layer_t layerId)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
-#else
auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
-#endif
auto error = static_cast<Error>(intError);
ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
" failed: %s (%d)", mId, layerId, to_string(error).c_str(),
@@ -1189,13 +788,8 @@
Error Layer::setCursorPosition(int32_t x, int32_t y)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
- mDisplayId, mId, x, y);
-#else
auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
mId, x, y);
-#endif
return static_cast<Error>(intError);
}
@@ -1203,19 +797,8 @@
const sp<Fence>& acquireFence)
{
int32_t fenceFd = acquireFence->dup();
-#ifdef BYPASS_IHWC
- (void) slot;
- buffer_handle_t handle = nullptr;
- if (buffer.get() && buffer->getNativeBuffer()) {
- handle = buffer->getNativeBuffer()->handle;
- }
-
- int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
- mId, handle, fenceFd);
-#else
auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
mId, slot, buffer, fenceFd);
-#endif
return static_cast<Error>(intError);
}
@@ -1223,44 +806,22 @@
{
// We encode default full-screen damage as INVALID_RECT upstream, but as 0
// rects for HWC
-#ifdef BYPASS_IHWC
- int32_t intError = 0;
-#else
Hwc2::Error intError = Hwc2::Error::NONE;
-#endif
if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
-#ifdef BYPASS_IHWC
- intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
- mDisplayId, mId, {0, nullptr});
-#else
intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
mId, std::vector<Hwc2::IComposerClient::Rect>());
-#endif
} else {
size_t rectCount = 0;
auto rectArray = damage.getArray(&rectCount);
-#ifdef BYPASS_IHWC
- std::vector<hwc_rect_t> hwcRects;
-#else
std::vector<Hwc2::IComposerClient::Rect> hwcRects;
-#endif
for (size_t rect = 0; rect < rectCount; ++rect) {
hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
rectArray[rect].right, rectArray[rect].bottom});
}
-#ifdef BYPASS_IHWC
- hwc_region_t hwcRegion = {};
- hwcRegion.numRects = rectCount;
- hwcRegion.rects = hwcRects.data();
-
- intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
- mDisplayId, mId, hwcRegion);
-#else
intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
mId, hwcRects);
-#endif
}
return static_cast<Error>(intError);
@@ -1268,83 +829,49 @@
Error Layer::setBlendMode(BlendMode mode)
{
-#ifdef BYPASS_IHWC
- auto intMode = static_cast<int32_t>(mode);
- int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
- mDisplayId, mId, intMode);
-#else
auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
mId, intMode);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setColor(hwc_color_t color)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
- mId, color);
-#else
Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
mId, hwcColor);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setCompositionType(Composition type)
{
-#ifdef BYPASS_IHWC
- auto intType = static_cast<int32_t>(type);
- int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
- mDisplayId, mId, intType);
-#else
auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
mId, intType);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setDataspace(android_dataspace_t dataspace)
{
-#ifdef BYPASS_IHWC
- auto intDataspace = static_cast<int32_t>(dataspace);
- int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
- mDisplayId, mId, intDataspace);
-#else
auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
mId, intDataspace);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setDisplayFrame(const Rect& frame)
{
-#ifdef BYPASS_IHWC
- hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
- int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
- mDisplayId, mId, hwcRect);
-#else
Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
frame.right, frame.bottom};
auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
mId, hwcRect);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setPlaneAlpha(float alpha)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
- mDisplayId, mId, alpha);
-#else
auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
mId, alpha);
-#endif
return static_cast<Error>(intError);
}
@@ -1355,42 +882,25 @@
"device supports sideband streams");
return Error::Unsupported;
}
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
- mDisplayId, mId, stream);
-#else
auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
mId, stream);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setSourceCrop(const FloatRect& crop)
{
-#ifdef BYPASS_IHWC
- hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
- int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
- mDisplayId, mId, hwcRect);
-#else
Hwc2::IComposerClient::FRect hwcRect{
crop.left, crop.top, crop.right, crop.bottom};
auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
mId, hwcRect);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setTransform(Transform transform)
{
-#ifdef BYPASS_IHWC
- auto intTransform = static_cast<int32_t>(transform);
- int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
- mDisplayId, mId, intTransform);
-#else
auto intTransform = static_cast<Hwc2::Transform>(transform);
auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
mId, intTransform);
-#endif
return static_cast<Error>(intError);
}
@@ -1399,50 +909,26 @@
size_t rectCount = 0;
auto rectArray = region.getArray(&rectCount);
-#ifdef BYPASS_IHWC
- std::vector<hwc_rect_t> hwcRects;
-#else
std::vector<Hwc2::IComposerClient::Rect> hwcRects;
-#endif
for (size_t rect = 0; rect < rectCount; ++rect) {
hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
rectArray[rect].right, rectArray[rect].bottom});
}
-#ifdef BYPASS_IHWC
- hwc_region_t hwcRegion = {};
- hwcRegion.numRects = rectCount;
- hwcRegion.rects = hwcRects.data();
-
- int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
- mDisplayId, mId, hwcRegion);
-#else
auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
mId, hwcRects);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setZOrder(uint32_t z)
{
-#ifdef BYPASS_IHWC
- int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
- mId, z);
-#else
auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
-#endif
return static_cast<Error>(intError);
}
Error Layer::setInfo(uint32_t type, uint32_t appId)
{
-#ifdef BYPASS_IHWC
- (void)type;
- (void)appId;
- int32_t intError = 0;
-#else
auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
-#endif
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 643b1e0..97582a7 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -62,14 +62,10 @@
class Device
{
public:
-#ifdef BYPASS_IHWC
- explicit Device(hwc2_device_t* device);
-#else
// useVrComposer is passed to the composer HAL. When true, the composer HAL
// will use the vr composer service, otherwise it uses the real hardware
// composer.
Device(bool useVrComposer);
-#endif
~Device();
friend class HWC2::Display;
@@ -107,43 +103,12 @@
bool hasCapability(HWC2::Capability capability) const;
-#ifdef BYPASS_IHWC
- android::Hwc2::Composer* getComposer() { return nullptr; }
-#else
android::Hwc2::Composer* getComposer() { return mComposer.get(); }
-#endif
private:
// Initialization methods
-#ifdef BYPASS_IHWC
- template <typename PFN>
- [[clang::warn_unused_result]] bool loadFunctionPointer(
- FunctionDescriptor desc, PFN& outPFN) {
- auto intDesc = static_cast<int32_t>(desc);
- auto pfn = mHwcDevice->getFunction(mHwcDevice, intDesc);
- if (pfn != nullptr) {
- outPFN = reinterpret_cast<PFN>(pfn);
- return true;
- } else {
- ALOGE("Failed to load function %s", to_string(desc).c_str());
- return false;
- }
- }
-
- template <typename PFN, typename HOOK>
- void registerCallback(Callback callback, HOOK hook) {
- static_assert(std::is_same<PFN, HOOK>::value,
- "Incompatible function pointer");
- auto intCallback = static_cast<int32_t>(callback);
- auto callbackData = static_cast<hwc2_callback_data_t>(this);
- auto pfn = reinterpret_cast<hwc2_function_pointer_t>(hook);
- mRegisterCallback(mHwcDevice, intCallback, callbackData, pfn);
- }
-#endif
-
void loadCapabilities();
- void loadFunctionPointers();
void registerCallbacks();
// For use by Display
@@ -151,60 +116,7 @@
void destroyVirtualDisplay(hwc2_display_t display);
// Member variables
-
-#ifdef BYPASS_IHWC
- hwc2_device_t* mHwcDevice;
-
- // Device function pointers
- HWC2_PFN_CREATE_VIRTUAL_DISPLAY mCreateVirtualDisplay;
- HWC2_PFN_DESTROY_VIRTUAL_DISPLAY mDestroyVirtualDisplay;
- HWC2_PFN_DUMP mDump;
- HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT mGetMaxVirtualDisplayCount;
- HWC2_PFN_REGISTER_CALLBACK mRegisterCallback;
-
- // Display function pointers
- HWC2_PFN_ACCEPT_DISPLAY_CHANGES mAcceptDisplayChanges;
- HWC2_PFN_CREATE_LAYER mCreateLayer;
- HWC2_PFN_DESTROY_LAYER mDestroyLayer;
- HWC2_PFN_GET_ACTIVE_CONFIG mGetActiveConfig;
- HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES mGetChangedCompositionTypes;
- HWC2_PFN_GET_COLOR_MODES mGetColorModes;
- HWC2_PFN_GET_DISPLAY_ATTRIBUTE mGetDisplayAttribute;
- HWC2_PFN_GET_DISPLAY_CONFIGS mGetDisplayConfigs;
- HWC2_PFN_GET_DISPLAY_NAME mGetDisplayName;
- HWC2_PFN_GET_DISPLAY_REQUESTS mGetDisplayRequests;
- HWC2_PFN_GET_DISPLAY_TYPE mGetDisplayType;
- HWC2_PFN_GET_DOZE_SUPPORT mGetDozeSupport;
- HWC2_PFN_GET_HDR_CAPABILITIES mGetHdrCapabilities;
- HWC2_PFN_GET_RELEASE_FENCES mGetReleaseFences;
- HWC2_PFN_PRESENT_DISPLAY mPresentDisplay;
- HWC2_PFN_SET_ACTIVE_CONFIG mSetActiveConfig;
- HWC2_PFN_SET_CLIENT_TARGET mSetClientTarget;
- HWC2_PFN_SET_COLOR_MODE mSetColorMode;
- HWC2_PFN_SET_COLOR_TRANSFORM mSetColorTransform;
- HWC2_PFN_SET_OUTPUT_BUFFER mSetOutputBuffer;
- HWC2_PFN_SET_POWER_MODE mSetPowerMode;
- HWC2_PFN_SET_VSYNC_ENABLED mSetVsyncEnabled;
- HWC2_PFN_VALIDATE_DISPLAY mValidateDisplay;
-
- // Layer function pointers
- HWC2_PFN_SET_CURSOR_POSITION mSetCursorPosition;
- HWC2_PFN_SET_LAYER_BUFFER mSetLayerBuffer;
- HWC2_PFN_SET_LAYER_SURFACE_DAMAGE mSetLayerSurfaceDamage;
- HWC2_PFN_SET_LAYER_BLEND_MODE mSetLayerBlendMode;
- HWC2_PFN_SET_LAYER_COLOR mSetLayerColor;
- HWC2_PFN_SET_LAYER_COMPOSITION_TYPE mSetLayerCompositionType;
- HWC2_PFN_SET_LAYER_DATASPACE mSetLayerDataspace;
- HWC2_PFN_SET_LAYER_DISPLAY_FRAME mSetLayerDisplayFrame;
- HWC2_PFN_SET_LAYER_PLANE_ALPHA mSetLayerPlaneAlpha;
- HWC2_PFN_SET_LAYER_SIDEBAND_STREAM mSetLayerSidebandStream;
- HWC2_PFN_SET_LAYER_SOURCE_CROP mSetLayerSourceCrop;
- HWC2_PFN_SET_LAYER_TRANSFORM mSetLayerTransform;
- HWC2_PFN_SET_LAYER_VISIBLE_REGION mSetLayerVisibleRegion;
- HWC2_PFN_SET_LAYER_Z_ORDER mSetLayerZOrder;
-#else
std::unique_ptr<android::Hwc2::Composer> mComposer;
-#endif // BYPASS_IHWC
std::unordered_set<Capability> mCapabilities;
std::unordered_map<hwc2_display_t, std::weak_ptr<Display>> mDisplays;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 40979c9..431fa9d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -109,45 +109,7 @@
void HWComposer::loadHwcModule(bool useVrComposer)
{
ALOGV("loadHwcModule");
-
-#ifdef BYPASS_IHWC
- (void)useVrComposer; // Silence unused parameter warning.
-
- hw_module_t const* module;
-
- if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
- ALOGE("%s module not found, aborting", HWC_HARDWARE_MODULE_ID);
- abort();
- }
-
- hw_device_t* device = nullptr;
- int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
- if (error != 0) {
- ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
- abort();
- }
-
- uint32_t majorVersion = (device->version >> 24) & 0xF;
- if (majorVersion == 2) {
- mHwcDevice = std::make_unique<HWC2::Device>(
- reinterpret_cast<hwc2_device_t*>(device));
- } else {
- mAdapter = std::make_unique<HWC2On1Adapter>(
- reinterpret_cast<hwc_composer_device_1_t*>(device));
- uint8_t minorVersion = mAdapter->getHwc1MinorVersion();
- if (minorVersion < 1) {
- ALOGE("Cannot adapt to HWC version %d.%d",
- static_cast<int32_t>((minorVersion >> 8) & 0xF),
- static_cast<int32_t>(minorVersion & 0xF));
- abort();
- }
- mHwcDevice = std::make_unique<HWC2::Device>(
- static_cast<hwc2_device_t*>(mAdapter.get()));
- }
-#else
mHwcDevice = std::make_unique<HWC2::Device>(useVrComposer);
-#endif
-
mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
}
@@ -876,11 +838,7 @@
*/
bool HWComposer::isUsingVrComposer() const {
-#ifdef BYPASS_IHWC
- return false;
-#else
return getComposer()->isUsingVrComposer();
-#endif
}
void HWComposer::dump(String8& result) const {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp
index 6b91224..a234b63 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp
@@ -29,10 +29,6 @@
const sp<GraphicBuffer>& buffer,
uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
{
-#ifdef BYPASS_IHWC
- *outSlot = slot;
- *outBuffer = buffer;
-#else
if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
// default to slot 0
slot = 0;
@@ -53,7 +49,6 @@
// update cache
mBuffers[slot] = buffer;
}
-#endif
}
} // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8220d0a..ae731f7 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -34,6 +34,7 @@
#include <utils/StopWatch.h>
#include <utils/Trace.h>
+#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
@@ -873,9 +874,6 @@
}
}
-android_dataspace Layer::getDataSpace() const {
- return mCurrentState.dataSpace;
-}
#else
void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer) {
@@ -1886,6 +1884,10 @@
return true;
}
+android_dataspace Layer::getDataSpace() const {
+ return mCurrentState.dataSpace;
+}
+
uint32_t Layer::getLayerStack() const {
auto p = getParent();
if (p == nullptr) {
@@ -2331,11 +2333,17 @@
visibleRegion.dump(result, "visibleRegion");
surfaceDamageRegion.dump(result, "surfaceDamageRegion");
sp<Client> client(mClientRef.promote());
+ PixelFormat pf = PIXEL_FORMAT_UNKNOWN;
+ const sp<GraphicBuffer>& buffer(getActiveBuffer());
+ if (buffer != NULL) {
+ pf = buffer->getPixelFormat();
+ }
result.appendFormat( " "
"layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
"crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
"isOpaque=%1d, invalidate=%1d, "
+ "dataspace=%s, pixelformat=%s "
#ifdef USE_HWC2
"alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
#else
@@ -2350,6 +2358,7 @@
s.finalCrop.left, s.finalCrop.top,
s.finalCrop.right, s.finalCrop.bottom,
isOpaque(s), contentDirty,
+ dataspaceDetails(getDataSpace()).c_str(), decodePixelFormat(pf).c_str(),
s.alpha, s.flags,
s.active.transform[0][0], s.active.transform[0][1],
s.active.transform[1][0], s.active.transform[1][1],
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9f45435..92353ae 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -192,6 +192,7 @@
bool setFlags(uint8_t flags, uint8_t mask);
bool setLayerStack(uint32_t layerStack);
bool setDataSpace(android_dataspace dataSpace);
+ android_dataspace getDataSpace() const;
uint32_t getLayerStack() const;
void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
@@ -275,8 +276,6 @@
void forceClientComposition(int32_t hwcId);
void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
- android_dataspace getDataSpace() const;
-
// callIntoHwc exists so we can update our local state and call
// acceptDisplayChanges without unnecessarily updating the device's state
void setCompositionType(int32_t hwcId, HWC2::Composition type,
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 04fe182..18b2e1b 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -143,7 +143,7 @@
// Compute sRGB to DisplayP3 color transform
// NOTE: For now, we are limiting wide-color support to
// Display-P3 only.
- mat3 srgbToP3 = ColorSpace::DisplayP3().getXYZtoRGB() * ColorSpace::sRGB().getRGBtoXYZ();
+ mat3 srgbToP3 = ColorSpaceConnector(ColorSpace::sRGB(), ColorSpace::DisplayP3()).getTransform();
// color transform needs to be transposed and expanded to 4x4
// to be what the shader wants
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 7564269..f8785db 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -54,12 +54,16 @@
// both a 16-bit primary display framebuffer and a 32-bit virtual display
// framebuffer.
//
+ // EGL_KHR_no_config_context is official extension to allow creating a
+ // context that works with any surface of a display.
+ //
// The code assumes that ES2 or later is available if this extension is
// supported.
EGLConfig config = EGL_NO_CONFIG;
- if (!findExtension(
- eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
- "EGL_ANDROIDX_no_config_context")) {
+ if (!findExtension(eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
+ "EGL_ANDROIDX_no_config_context") &&
+ !findExtension(eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS),
+ "EGL_KHR_no_config_context")) {
config = chooseEglConfig(display, hwcFormat);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fec1f1e..505e81c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2646,6 +2646,8 @@
{
Mutex::Autolock _l(mStateLock);
if (mNumLayers >= MAX_LAYERS) {
+ ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
+ MAX_LAYERS);
return NO_MEMORY;
}
if (parent == nullptr) {
@@ -3211,6 +3213,22 @@
getHwComposer().setPowerMode(type, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
+ } else if (mode == HWC_POWER_MODE_DOZE) {
+ // Update display while dozing
+ getHwComposer().setPowerMode(type, mode);
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenAcquired();
+ resyncToHardwareVsync(true);
+ }
+ } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ // Leave display going to doze
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ disableHardwareVsync(true); // also cancels any in-progress resync
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenReleased();
+ }
+ getHwComposer().setPowerMode(type, mode);
} else {
getHwComposer().setPowerMode(type, mode);
}
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 7070b97..290d31e 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2877,6 +2877,22 @@
getHwComposer().setPowerMode(type, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
+ } else if (mode == HWC_POWER_MODE_DOZE) {
+ // Update display while dozing
+ getHwComposer().setPowerMode(type, mode);
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenAcquired();
+ resyncToHardwareVsync(true);
+ }
+ } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ // Leave display going to doze
+ if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ disableHardwareVsync(true); // also cancels any in-progress resync
+ // FIXME: eventthread only knows about the main display right now
+ mEventThread->onScreenReleased();
+ }
+ getHwComposer().setPowerMode(type, mode);
} else {
getHwComposer().setPowerMode(type, mode);
}
diff --git a/services/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk
index 16041da..43e22a0 100644
--- a/services/surfaceflinger/tests/Android.mk
+++ b/services/surfaceflinger/tests/Android.mk
@@ -4,7 +4,7 @@
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE := SurfaceFlinger_test
-
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := \
diff --git a/services/surfaceflinger/tests/AndroidTest.xml b/services/surfaceflinger/tests/AndroidTest.xml
new file mode 100644
index 0000000..8315037
--- /dev/null
+++ b/services/surfaceflinger/tests/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for SurfaceFlinger_test">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="SurfaceFlinger_test->/data/local/tmp/SurfaceFlinger_test" />
+ </target_preparer>
+ <option name="test-suite-tag" value="apct" />
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="SurfaceFlinger_test" />
+ </test>
+</configuration>
diff --git a/services/surfaceflinger/tests/vsync/Android.mk b/services/surfaceflinger/tests/vsync/Android.mk
index 9181760..8e41617 100644
--- a/services/surfaceflinger/tests/vsync/Android.mk
+++ b/services/surfaceflinger/tests/vsync/Android.mk
@@ -15,4 +15,6 @@
LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS := -Werror
+
include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp
index aa72c79..a1b45e6 100644
--- a/services/surfaceflinger/tests/vsync/vsync.cpp
+++ b/services/surfaceflinger/tests/vsync/vsync.cpp
@@ -20,7 +20,7 @@
using namespace android;
-int receiver(int fd, int events, void* data)
+int receiver(int /*fd*/, int /*events*/, void* data)
{
DisplayEventReceiver* q = (DisplayEventReceiver*)data;
@@ -47,7 +47,7 @@
return 1;
}
-int main(int argc, char** argv)
+int main(int /*argc*/, char** /*argv*/)
{
DisplayEventReceiver myDisplayEvent;
diff --git a/services/surfaceflinger/tests/waitforvsync/Android.mk b/services/surfaceflinger/tests/waitforvsync/Android.mk
index c25f5ab..932d2be 100644
--- a/services/surfaceflinger/tests/waitforvsync/Android.mk
+++ b/services/surfaceflinger/tests/waitforvsync/Android.mk
@@ -11,4 +11,6 @@
LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS := -Werror
+
include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
index b88b04a..65eaae5 100644
--- a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
+++ b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
@@ -29,7 +29,7 @@
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
#endif
-int main(int argc, char** argv) {
+int main(int /*argc*/, char** /*argv*/) {
int fd = open("/dev/graphics/fb0", O_RDWR);
if (fd >= 0) {
do {
diff --git a/services/vr/sensord/Android.mk b/services/vr/sensord/Android.mk
deleted file mode 100644
index 638c9a8..0000000
--- a/services/vr/sensord/Android.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-SENSORD_EXTEND ?= libsensordextensionstub
-
-sourceFiles := \
- pose_service.cpp \
- sensord.cpp \
- sensor_fusion.cpp \
- sensor_hal_thread.cpp \
- sensor_ndk_thread.cpp \
- sensor_service.cpp \
- sensor_thread.cpp \
-
-includeFiles += \
- $(LOCAL_PATH)/include
-
-staticLibraries := \
- libdvrcommon \
- libvrsensor \
- libperformance \
- libbufferhub \
- libpdx_default_transport \
- libposepredictor \
-
-sharedLibraries := \
- libandroid \
- libbase \
- libbinder \
- libcutils \
- liblog \
- libhardware \
- libutils \
- libui \
- $(SENSORD_EXTEND) \
-
-cFlags := -DLOG_TAG=\"sensord\" \
- -DTRACE=0
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_CFLAGS := $(cFlags)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := sensord
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_C_INCLUDES += \
- $(call local-generated-sources-dir)/proto/frameworks/native/services/vr/sensord
-LOCAL_INIT_RC := sensord.rc
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_SRC_FILES := test/poselatencytest.cpp
-LOCAL_MODULE := poselatencytest
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libsensordextensionstub
-LOCAL_SRC_FILES := sensord_extension.cpp
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/vr/sensord/pose_service.cpp b/services/vr/sensord/pose_service.cpp
deleted file mode 100644
index 75423bb..0000000
--- a/services/vr/sensord/pose_service.cpp
+++ /dev/null
@@ -1,649 +0,0 @@
-#define ATRACE_TAG ATRACE_TAG_INPUT
-#include "pose_service.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <time.h>
-
-#include <array>
-#include <cmath>
-#include <cstdint>
-#include <sstream>
-#include <type_traits>
-
-#include <cutils/properties.h>
-#include <cutils/trace.h>
-#include <dvr/performance_client_api.h>
-#include <dvr/pose_client.h>
-#include <hardware/sensors.h>
-#include <log/log.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <private/dvr/benchmark.h>
-#include <private/dvr/clock_ns.h>
-#include <private/dvr/platform_defines.h>
-#include <private/dvr/pose-ipc.h>
-#include <private/dvr/sensor_constants.h>
-#include <utils/Trace.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-using Vector3d = vec3d;
-using Rotationd = quatd;
-using AngleAxisd = Eigen::AngleAxis<double>;
-
-namespace {
-// Wait a few seconds before checking if we need to disable sensors.
-static constexpr int64_t kSensorTimeoutNs = 5000000000ll;
-
-static constexpr float kTwoPi = 2.0 * M_PI;
-static constexpr float kDegToRad = M_PI / 180.f;
-
-// Head model code data.
-static constexpr float kDefaultNeckHorizontalOffset = 0.080f; // meters
-static constexpr float kDefaultNeckVerticalOffset = 0.075f; // meters
-
-static constexpr char kDisablePosePredictionProp[] =
- "persist.dvr.disable_predict";
-
-// Device type property for controlling classes of behavior that differ
-// between devices. If unset, defaults to kOrientationTypeSmartphone.
-static constexpr char kOrientationTypeProp[] = "ro.dvr.orientation_type";
-static constexpr char kEnableSensorRecordProp[] = "dvr.enable_6dof_recording";
-static constexpr char kEnableSensorPlayProp[] = "dvr.enable_6dof_playback";
-static constexpr char kEnableSensorPlayIdProp[] = "dvr.6dof_playback_id";
-static constexpr char kEnablePoseRecordProp[] = "dvr.enable_pose_recording";
-static constexpr char kPredictorTypeProp[] = "dvr.predictor_type";
-
-// Persistent buffer names.
-static constexpr char kPoseRingBufferName[] = "PoseService:RingBuffer";
-
-static constexpr int kDatasetIdLength = 36;
-static constexpr char kDatasetIdChars[] = "0123456789abcdef-";
-
-static constexpr int kLatencyWindowSize = 200;
-
-// These are the flags used by BufferProducer::CreatePersistentUncachedBlob,
-// plus PRIVATE_ADSP_HEAP to allow access from the DSP.
-static constexpr int kPoseRingBufferFlags =
- GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY |
- GRALLOC_USAGE_PRIVATE_UNCACHED | GRALLOC_USAGE_PRIVATE_ADSP_HEAP;
-
-std::string GetPoseModeString(DvrPoseMode mode) {
- switch (mode) {
- case DVR_POSE_MODE_6DOF:
- return "DVR_POSE_MODE_6DOF";
- case DVR_POSE_MODE_3DOF:
- return "DVR_POSE_MODE_3DOF";
- case DVR_POSE_MODE_MOCK_FROZEN:
- return "DVR_POSE_MODE_MOCK_FROZEN";
- case DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW:
- return "DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW";
- case DVR_POSE_MODE_MOCK_HEAD_TURN_FAST:
- return "DVR_POSE_MODE_MOCK_HEAD_TURN_FAST";
- case DVR_POSE_MODE_MOCK_ROTATE_SLOW:
- return "DVR_POSE_MODE_MOCK_ROTATE_SLOW";
- case DVR_POSE_MODE_MOCK_ROTATE_MEDIUM:
- return "DVR_POSE_MODE_MOCK_ROTATE_MEDIUM";
- case DVR_POSE_MODE_MOCK_ROTATE_FAST:
- return "DVR_POSE_MODE_MOCK_ROTATE_FAST";
- case DVR_POSE_MODE_MOCK_CIRCLE_STRAFE:
- return "DVR_POSE_MODE_MOCK_CIRCLE_STRAFE";
- default:
- return "Unknown pose mode";
- }
-}
-
-} // namespace
-
-PoseService::PoseService(SensorThread* sensor_thread)
- : BASE("PoseService", Endpoint::Create(DVR_POSE_SERVICE_CLIENT)),
- sensor_thread_(sensor_thread),
- last_sensor_usage_time_ns_(0),
- watchdog_shutdown_(false),
- sensors_on_(false),
- accelerometer_index_(-1),
- gyroscope_index_(-1),
- pose_mode_(DVR_POSE_MODE_6DOF),
- mapped_pose_buffer_(nullptr),
- vsync_count_(0),
- photon_timestamp_(0),
- // Will be updated by external service, but start with a non-zero value:
- display_period_ns_(16000000),
- sensor_latency_(kLatencyWindowSize) {
- last_known_pose_ = {
- .orientation = {1.0f, 0.0f, 0.0f, 0.0f},
- .translation = {0.0f, 0.0f, 0.0f, 0.0f},
- .angular_velocity = {0.0f, 0.0f, 0.0f, 0.0f},
- .velocity = {0.0f, 0.0f, 0.0f, 0.0f},
- .timestamp_ns = 0,
- .flags = DVR_POSE_FLAG_HEAD,
- .pad = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- };
-
- switch (property_get_int32(kOrientationTypeProp, kOrientationTypePortrait)) {
- case kOrientationTypeLandscape:
- device_orientation_type_ = kOrientationTypeLandscape;
- break;
- default:
- device_orientation_type_ = kOrientationTypePortrait;
- break;
- }
-
- ring_buffer_ =
- BufferProducer::Create(kPoseRingBufferName, 0, 0, kPoseRingBufferFlags,
- sizeof(DvrPoseRingBuffer));
- if (!ring_buffer_) {
- ALOGE("PoseService::PoseService: Failed to create/get pose ring buffer!");
- return;
- }
-
- void* addr = nullptr;
- int ret =
- ring_buffer_->GetBlobReadWritePointer(sizeof(DvrPoseRingBuffer), &addr);
- if (ret < 0) {
- ALOGE("PoseService::PoseService: Failed to map pose ring buffer: %s",
- strerror(-ret));
- return;
- }
- memset(addr, 0, sizeof(DvrPoseRingBuffer));
- mapped_pose_buffer_ = static_cast<DvrPoseRingBuffer*>(addr);
- addr = nullptr;
-
- for (int i = 0; i < sensor_thread->GetSensorCount(); ++i) {
- if (sensor_thread->GetSensorType(i) == SENSOR_TYPE_ACCELEROMETER)
- accelerometer_index_ = i;
- if (sensor_thread->GetSensorType(i) == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED)
- gyroscope_index_ = i;
- }
- // If we failed to find the uncalibrated gyroscope, use the regular one.
- if (gyroscope_index_ < 0) {
- ALOGW("PoseService was unable to find uncalibrated gyroscope");
- for (int i = 0; i < sensor_thread->GetSensorCount(); ++i) {
- ALOGI("Type %d", sensor_thread->GetSensorType(i));
- if (sensor_thread->GetSensorType(i) == SENSOR_TYPE_GYROSCOPE)
- gyroscope_index_ = i;
- }
- }
-
- if (accelerometer_index_ < 0) {
- ALOGE("PoseService was unable to find accelerometer");
- }
- if (gyroscope_index_ < 0) {
- ALOGE("PoseService was unable to find gyroscope");
- }
-
- {
- std::lock_guard<std::mutex> lock(mutex_);
- KickSensorWatchDogThread();
- }
-
- // Read the persistent dvr flags before using them in SetPoseMode.
- enable_pose_prediction_ =
- property_get_bool(kDisablePosePredictionProp, 0) == 0;
-
- enable_sensor_recording_ = property_get_bool(kEnableSensorRecordProp, 0) == 1;
-
- enable_sensor_playback_ = property_get_bool(kEnableSensorPlayProp, 0) == 1;
-
- if (enable_sensor_playback_) {
- char dataset_id[PROPERTY_VALUE_MAX];
- property_get(kEnableSensorPlayIdProp, dataset_id, "");
- sensor_playback_id_ = std::string(dataset_id);
-
- if (sensor_playback_id_.length() != kDatasetIdLength ||
- sensor_playback_id_.find_first_not_of(kDatasetIdChars) !=
- std::string::npos) {
- ALOGE("Error: invalid playback id %s", sensor_playback_id_.c_str());
- sensor_playback_id_ = "";
- enable_sensor_playback_ = false;
- } else {
- ALOGI("Playback id %s", sensor_playback_id_.c_str());
- }
- }
-
- switch (property_get_int32(kPredictorTypeProp, 0)) {
- case 1:
- pose_predictor_ = posepredictor::Predictor::Create(
- posepredictor::PredictorType::Quadric);
- default:
- pose_predictor_ = posepredictor::Predictor::Create(
- posepredictor::PredictorType::Linear);
- }
-
- enable_pose_recording_ = property_get_bool(kEnablePoseRecordProp, 0) == 1;
-
- SetPoseMode(DVR_POSE_MODE_6DOF);
-}
-
-PoseService::~PoseService() {
- if (watchdog_thread_.get_id() != std::thread::id()) {
- {
- std::lock_guard<std::mutex> guard(mutex_);
- watchdog_shutdown_ = true;
- watchdog_condition_.notify_one();
- }
- watchdog_thread_.join();
- }
-}
-
-void PoseService::KickSensorWatchDogThread() {
- // This method is called every frame while rendering so we want to make sure
- // it is very light weight with synchronization.
- // TODO(jbates) For better performance, we can consider a lock-free atomic
- // solution instead of locking this mutex.
-
- // Update the usage time. The watchdog thread will poll this value to know
- // when to disable sensors.
- last_sensor_usage_time_ns_ = GetSystemClockNs();
-
- // If sensors are still on, there's nothing else to do.
- if (sensors_on_)
- return;
-
- // Enable sensors.
- ALOGI("Start using sensors.");
- sensors_on_ = true;
- if (accelerometer_index_ >= 0) {
- sensor_thread_->StartUsingSensor(accelerometer_index_);
- }
- if (gyroscope_index_ >= 0) {
- sensor_thread_->StartUsingSensor(gyroscope_index_);
- }
-
- // Tell the thread to wake up to disable the sensors when no longer needed.
- watchdog_condition_.notify_one();
-
- if (watchdog_thread_.get_id() == std::thread::id()) {
- // The sensor watchdog thread runs while sensors are in use. When no APIs
- // have requested sensors beyond a threshold (5 seconds), sensors are
- // disabled.
- watchdog_thread_ = std::thread([this] {
- std::unique_lock<std::mutex> lock(mutex_);
- while (!watchdog_shutdown_) {
- int64_t remaining_sensor_time_ns =
- last_sensor_usage_time_ns_ + kSensorTimeoutNs - GetSystemClockNs();
-
- if (remaining_sensor_time_ns > 0) {
- // Wait for the remaining usage time before checking again.
- watchdog_condition_.wait_for(
- lock, std::chrono::nanoseconds(remaining_sensor_time_ns));
- continue;
- }
-
- if (sensors_on_) {
- // Disable sensors.
- ALOGI("Stop using sensors.");
- sensors_on_ = false;
- if (accelerometer_index_ >= 0) {
- sensor_thread_->StopUsingSensor(accelerometer_index_);
- }
- if (gyroscope_index_ >= 0) {
- sensor_thread_->StopUsingSensor(gyroscope_index_);
- }
- }
-
- // Wait for sensors to be enabled again.
- watchdog_condition_.wait(lock);
- }
- });
- }
-}
-
-bool PoseService::IsInitialized() const {
- return BASE::IsInitialized() && ring_buffer_ && mapped_pose_buffer_;
-}
-
-void PoseService::WriteAsyncPoses(const Vector3d& start_t_head,
- const Rotationd& start_q_head,
- int64_t pose_timestamp) {
- if (enable_external_pose_) {
- return;
- }
-
- // If playing back data, the timestamps are different enough from the
- // current time that prediction doesn't work. This hack pretends that
- // there was one nanosecond of latency between the sensors and here.
- if (enable_sensor_playback_)
- pose_timestamp = GetSystemClockNs() - 1;
-
- // Feed the sample to the predictor
- AddPredictorPose(pose_predictor_.get(), start_t_head, start_q_head,
- pose_timestamp, &last_known_pose_);
-
- // Store one extra value, because the application is working on the next
- // frame and expects the minimum count from that frame on.
- for (uint32_t i = 0; i < kPoseAsyncBufferMinFutureCount + 1; ++i) {
- int64_t target_time = photon_timestamp_ + i * display_period_ns_;
-
- // TODO(jbates, cwolfe) For the DSP code, we may still want poses even when
- // the vsyncs are not ticking up. But it's important not to update the pose
- // data that's in the past so that applications have the most accurate
- // estimate of the last frame's *actual* pose, so that they can update
- // simulations and calculate collisions, etc.
- if (target_time < pose_timestamp) {
- // Already in the past, do not update this head pose slot.
- continue;
- }
-
- // Write to the actual shared memory ring buffer.
- uint32_t index = ((vsync_count_ + i) & kPoseAsyncBufferIndexMask);
-
- // Make a pose prediction
- if (enable_pose_prediction_) {
- PredictPose(pose_predictor_.get(), target_time,
- target_time + right_eye_photon_offset_ns_,
- mapped_pose_buffer_->ring + index);
- } else {
- mapped_pose_buffer_->ring[index] = last_known_pose_;
- }
- }
-}
-
-void PoseService::UpdatePoseMode() {
- ALOGI_IF(TRACE, "UpdatePoseMode: %f %f %f", last_known_pose_.translation[0],
- last_known_pose_.translation[1], last_known_pose_.translation[2]);
-
- const int64_t current_time_ns = GetSystemClockNs();
-
- const PoseState pose_state = sensor_fusion_.GetLatestPoseState();
-
- switch (pose_mode_) {
- case DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW:
- case DVR_POSE_MODE_MOCK_HEAD_TURN_FAST:
- case DVR_POSE_MODE_MOCK_ROTATE_SLOW:
- case DVR_POSE_MODE_MOCK_ROTATE_MEDIUM:
- case DVR_POSE_MODE_MOCK_ROTATE_FAST:
- case DVR_POSE_MODE_MOCK_CIRCLE_STRAFE: {
- // Calculate a pose based on monotic system time.
- const Vector3d y_axis(0., 1., 0.);
- double time_s = current_time_ns / 1e9;
-
- // Generate fake yaw data.
- float yaw = 0.0f;
- Vector3d head_trans(0.0, 0.0, 0.0);
- switch (pose_mode_) {
- default:
- case DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW:
- // Pan across 120 degrees in 15 seconds.
- yaw = std::cos(kTwoPi * time_s / 15.0) * 60.0 * kDegToRad;
- break;
- case DVR_POSE_MODE_MOCK_HEAD_TURN_FAST:
- // Pan across 120 degrees in 4 seconds.
- yaw = std::cos(kTwoPi * time_s / 4.0) * 60.0 * kDegToRad;
- break;
- case DVR_POSE_MODE_MOCK_ROTATE_SLOW:
- // Rotate 5 degrees per second.
- yaw = std::fmod(time_s * 5.0 * kDegToRad, kTwoPi);
- break;
- case DVR_POSE_MODE_MOCK_ROTATE_MEDIUM:
- // Rotate 30 degrees per second.
- yaw = std::fmod(time_s * 30.0 * kDegToRad, kTwoPi);
- break;
- case DVR_POSE_MODE_MOCK_ROTATE_FAST:
- // Rotate 90 degrees per second.
- yaw = std::fmod(time_s * 90.0 * kDegToRad, kTwoPi);
- break;
- case DVR_POSE_MODE_MOCK_CIRCLE_STRAFE:
- // Circle strafe around origin at distance of 3 meters.
- yaw = std::fmod(time_s * 30.0 * kDegToRad, kTwoPi);
- head_trans += 3.0 * Vector3d(sin(yaw), 0.0, cos(yaw));
- break;
- }
-
- // Calculate the simulated head rotation in an absolute "head" space.
- // This space is not related to start space and doesn't need a
- // reference.
- Rotationd head_rotation_in_head_space(AngleAxisd(yaw, y_axis));
-
- WriteAsyncPoses(head_trans, head_rotation_in_head_space, current_time_ns);
- break;
- }
- case DVR_POSE_MODE_MOCK_FROZEN: {
- // Even when frozen, we still provide a current timestamp, because
- // consumers may rely on it being monotonic.
-
- Rotationd start_from_head_rotation(
- frozen_state_.head_from_start_rotation.w,
- frozen_state_.head_from_start_rotation.x,
- frozen_state_.head_from_start_rotation.y,
- frozen_state_.head_from_start_rotation.z);
- Vector3d head_from_start_translation(
- frozen_state_.head_from_start_translation.x,
- frozen_state_.head_from_start_translation.y,
- frozen_state_.head_from_start_translation.z);
-
- WriteAsyncPoses(head_from_start_translation, start_from_head_rotation,
- current_time_ns);
- break;
- }
- case DVR_POSE_MODE_3DOF: {
- // Sensor fusion provides IMU-space data, transform to world space.
-
- // Constants to perform IMU orientation adjustments. Note that these
- // calculations will be optimized out in a release build.
- constexpr double k90DegInRad = 90.0 * M_PI / 180.0;
- const Vector3d kVecAxisX(1.0, 0.0, 0.0);
- const Vector3d kVecAxisY(0.0, 1.0, 0.0);
- const Vector3d kVecAxisZ(0.0, 0.0, 1.0);
- const Rotationd kRotX90(AngleAxisd(k90DegInRad, kVecAxisX));
-
- Rotationd start_from_head_rotation;
- if (device_orientation_type_ == kOrientationTypeLandscape) {
- const Rotationd kPostRotation =
- kRotX90 * Rotationd(AngleAxisd(-k90DegInRad, kVecAxisY));
- start_from_head_rotation =
- (pose_state.sensor_from_start_rotation * kPostRotation).inverse();
- } else if (device_orientation_type_ == kOrientationTypeLandscape180) {
- const Rotationd kPreRotation =
- Rotationd(AngleAxisd(k90DegInRad * 2.0, kVecAxisY)) *
- Rotationd(AngleAxisd(k90DegInRad * 2.0, kVecAxisZ));
- const Rotationd kPostRotation = kRotX90;
- start_from_head_rotation =
- (kPreRotation *
- pose_state.sensor_from_start_rotation * kPostRotation)
- .inverse();
- } else {
- const Rotationd kPreRotation =
- Rotationd(AngleAxisd(k90DegInRad, kVecAxisZ));
- const Rotationd kPostRotation = kRotX90;
- start_from_head_rotation =
- (kPreRotation * pose_state.sensor_from_start_rotation *
- kPostRotation)
- .inverse();
- }
- start_from_head_rotation.normalize();
-
- // Neck / head model code procedure for when no 6dof is available.
- // To apply the neck model, first translate the head pose to the new
- // center of eyes, then rotate around the origin (the original head
- // pos).
- Vector3d position =
- start_from_head_rotation * Vector3d(0.0, kDefaultNeckVerticalOffset,
- -kDefaultNeckHorizontalOffset);
-
- // Update the current latency model.
- if (pose_state.timestamp_ns != 0) {
- sensor_latency_.AddLatency(GetSystemClockNs() -
- pose_state.timestamp_ns);
- }
-
- // Update the timestamp with the expected latency.
- WriteAsyncPoses(
- position, start_from_head_rotation,
- pose_state.timestamp_ns + sensor_latency_.CurrentLatencyEstimate());
- break;
- }
- default:
- case DVR_POSE_MODE_6DOF:
- ALOGE("ERROR: invalid pose mode");
- break;
- }
-}
-
-pdx::Status<void> PoseService::HandleMessage(pdx::Message& msg) {
- pdx::Status<void> ret;
- const pdx::MessageInfo& info = msg.GetInfo();
- switch (info.op) {
- case DVR_POSE_NOTIFY_VSYNC: {
- std::lock_guard<std::mutex> guard(mutex_);
-
- // Kick the sensor thread, because we are still rendering.
- KickSensorWatchDogThread();
-
- const struct iovec data[] = {
- {.iov_base = &vsync_count_, .iov_len = sizeof(vsync_count_)},
- {.iov_base = &photon_timestamp_,
- .iov_len = sizeof(photon_timestamp_)},
- {.iov_base = &display_period_ns_,
- .iov_len = sizeof(display_period_ns_)},
- {.iov_base = &right_eye_photon_offset_ns_,
- .iov_len = sizeof(right_eye_photon_offset_ns_)},
- };
- ret = msg.ReadVectorAll(data);
- if (ret && !enable_external_pose_) {
- mapped_pose_buffer_->vsync_count = vsync_count_;
- }
-
- // TODO(jbates, eieio): make this async, no need to reply.
- REPLY_MESSAGE(msg, ret, error);
- }
- case DVR_POSE_POLL: {
- ATRACE_NAME("pose_poll");
- std::lock_guard<std::mutex> guard(mutex_);
-
- DvrPoseState client_state;
- client_state = {
- .head_from_start_rotation = {last_known_pose_.orientation[0],
- last_known_pose_.orientation[1],
- last_known_pose_.orientation[2],
- last_known_pose_.orientation[3]},
- .head_from_start_translation = {last_known_pose_.translation[0],
- last_known_pose_.translation[1],
- last_known_pose_.translation[2]},
- .timestamp_ns = static_cast<uint64_t>(last_known_pose_.timestamp_ns),
- .sensor_from_start_rotation_velocity = {
- last_known_pose_.angular_velocity[0],
- last_known_pose_.angular_velocity[1],
- last_known_pose_.angular_velocity[2]}};
-
- Btrace("Sensor data received",
- static_cast<int64_t>(client_state.timestamp_ns));
-
- Btrace("Pose polled");
-
- ret = msg.WriteAll(&client_state, sizeof(client_state));
- REPLY_MESSAGE(msg, ret, error);
- }
- case DVR_POSE_FREEZE: {
- {
- std::lock_guard<std::mutex> guard(mutex_);
-
- DvrPoseState frozen_state;
- ret = msg.ReadAll(&frozen_state, sizeof(frozen_state));
- if (!ret) {
- REPLY_ERROR(msg, ret.error(), error);
- }
- frozen_state_ = frozen_state;
- }
- SetPoseMode(DVR_POSE_MODE_MOCK_FROZEN);
- REPLY_MESSAGE(msg, ret, error);
- }
- case DVR_POSE_SET_MODE: {
- int mode;
- {
- std::lock_guard<std::mutex> guard(mutex_);
- ret = msg.ReadAll(&mode, sizeof(mode));
- if (!ret) {
- REPLY_ERROR(msg, ret.error(), error);
- }
- if (mode < 0 || mode >= DVR_POSE_MODE_COUNT) {
- REPLY_ERROR(msg, EINVAL, error);
- }
- }
- SetPoseMode(DvrPoseMode(mode));
- REPLY_MESSAGE(msg, ret, error);
- }
- case DVR_POSE_GET_MODE: {
- std::lock_guard<std::mutex> guard(mutex_);
- int mode = pose_mode_;
- ret = msg.WriteAll(&mode, sizeof(mode));
- REPLY_MESSAGE(msg, ret, error);
- }
- case DVR_POSE_GET_RING_BUFFER: {
- std::lock_guard<std::mutex> guard(mutex_);
-
- // Kick the sensor thread, because we have a new consumer.
- KickSensorWatchDogThread();
-
- Status<LocalChannelHandle> consumer_channel =
- ring_buffer_->CreateConsumer();
- REPLY_MESSAGE(msg, consumer_channel, error);
- }
- case DVR_POSE_GET_CONTROLLER_RING_BUFFER: {
- std::lock_guard<std::mutex> guard(mutex_);
- REPLY_ERROR(msg, EINVAL, error);
- }
- case DVR_POSE_LOG_CONTROLLER: {
- std::lock_guard<std::mutex> guard(mutex_);
- REPLY_ERROR(msg, EINVAL, error);
- }
- default:
- // Do not lock mutex_ here, because this may call the on*() handlers,
- // which will lock the mutex themselves.
- ret = Service::HandleMessage(msg);
- break;
- }
-error:
- return ret;
-}
-
-std::string PoseService::DumpState(size_t /*max_length*/) {
- DvrPoseMode pose_mode;
- {
- std::lock_guard<std::mutex> guard(mutex_);
- pose_mode = pose_mode_;
- }
-
- std::ostringstream stream;
- stream << "Pose mode: " << GetPoseModeString(pose_mode);
- return stream.str();
-}
-
-void PoseService::HandleEvents(const sensors_event_t* begin_events,
- const sensors_event_t* end_events) {
- ATRACE_NAME("PoseService::HandleEvents");
- std::lock_guard<std::mutex> guard(mutex_);
-
- for (const sensors_event_t* event = begin_events; event != end_events;
- ++event) {
- if (event->type == SENSOR_TYPE_ACCELEROMETER) {
- sensor_fusion_.ProcessAccelerometerSample(
- event->acceleration.x, event->acceleration.y, event->acceleration.z,
- event->timestamp);
- } else if (event->type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
- sensor_fusion_.ProcessGyroscopeSample(event->gyro.x, event->gyro.y,
- event->gyro.z, event->timestamp);
- }
- }
-
- UpdatePoseMode();
-}
-
-void PoseService::SetPoseMode(DvrPoseMode mode) {
- if (mode == DVR_POSE_MODE_6DOF) {
- // Only 3DoF is currently supported.
- mode = DVR_POSE_MODE_3DOF;
- }
-
- pose_mode_ = mode;
-
- sensor_thread_->SetPaused(false);
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/pose_service.h b/services/vr/sensord/pose_service.h
deleted file mode 100644
index 7b7adec..0000000
--- a/services/vr/sensord/pose_service.h
+++ /dev/null
@@ -1,149 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_POSE_SERVICE_H_
-#define ANDROID_DVR_SENSORD_POSE_SERVICE_H_
-
-#include <condition_variable>
-#include <forward_list>
-#include <mutex>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <dvr/pose_client.h>
-#include <pdx/service.h>
-#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/dvr_pose_predictor.h>
-#include <private/dvr/latency_model.h>
-#include <private/dvr/pose_client_internal.h>
-#include <private/dvr/ring_buffer.h>
-
-#include "sensor_fusion.h"
-#include "sensor_thread.h"
-
-namespace android {
-namespace dvr {
-
-// PoseService implements the HMD pose service over ServiceFS.
-class PoseService : public pdx::ServiceBase<PoseService> {
- public:
- ~PoseService() override;
-
- bool IsInitialized() const override;
- pdx::Status<void> HandleMessage(pdx::Message& msg) override;
- std::string DumpState(size_t max_length) override;
-
- // Handle events from the sensor HAL.
- // Safe to call concurrently with any other public member functions.
- void HandleEvents(const sensors_event_t* begin_events,
- const sensors_event_t* end_events);
-
- private:
- friend BASE;
-
- enum OrientationType {
- // Typical smartphone device (default).
- kOrientationTypePortrait = 1,
- // Landscape device.
- kOrientationTypeLandscape = 2,
- // 180 Landscape device.
- kOrientationTypeLandscape180 = 3,
- };
-
- // Initializes the service. Keeps a reference to sensor_thread, which must be
- // non-null.
- explicit PoseService(SensorThread* sensor_thread);
-
- // Kick the sensor watch dog thread which will robustly disable IMU usage
- // when there are no sensor data consumers.
- // The class mutex (mutex_) must be locked while calling this method.
- void KickSensorWatchDogThread();
-
- void UpdatePoseMode();
-
- // Update the async pose ring buffer with new pose data.
- // |start_t_head| Head position in start space.
- // |start_q_head| Head orientation quaternion in start space.
- // |pose_timestamp| System timestamp of pose data in seconds.
- // |pose_delta_time| Elapsed time in seconds between this pose and the last.
- void WriteAsyncPoses(const Eigen::Vector3<double>& start_t_head,
- const Eigen::Quaternion<double>& start_q_head,
- int64_t pose_timestamp);
-
- // Set the pose mode.
- void SetPoseMode(DvrPoseMode mode);
-
- // The abstraction around the sensor data.
- SensorThread* sensor_thread_;
-
- // Protects access to all member variables.
- std::mutex mutex_;
-
- // Watchdog thread data. The watchdog thread will ensure that sensor access
- // is disabled when nothing has been consuming it for a while.
- int64_t last_sensor_usage_time_ns_;
- std::thread watchdog_thread_;
- std::condition_variable watchdog_condition_;
- bool watchdog_shutdown_;
- bool sensors_on_;
-
- // Indices for the accelerometer and gyroscope sensors, or -1 if the sensor
- // wasn't present on construction.
- int accelerometer_index_;
- int gyroscope_index_;
-
- // The sensor fusion algorithm and its state.
- SensorFusion sensor_fusion_;
-
- // Current pose mode.
- DvrPoseMode pose_mode_;
-
- // State which is sent if pose_mode_ is DVR_POSE_MODE_MOCK_FROZEN.
- DvrPoseState frozen_state_;
-
- // Last known pose.
- DvrPoseAsync last_known_pose_;
-
- // If this flag is true, the pose published includes a small prediction of
- // where it'll be when it's consumed.
- bool enable_pose_prediction_;
-
- // Flag to turn on recording of raw sensor data
- bool enable_sensor_recording_;
-
- // Flag to log pose to a file
- bool enable_pose_recording_;
-
- // Flag to turn on playback from a saved dataset instead of using live data.
- bool enable_sensor_playback_;
-
- std::string sensor_playback_id_;
-
- // External pose generation.
- bool enable_external_pose_ = false;
-
- // The predictor to extrapolate pose samples.
- std::unique_ptr<posepredictor::Predictor> pose_predictor_;
-
- // Pose ring buffer.
- std::shared_ptr<BufferProducer> ring_buffer_;
- // Temporary mapped ring buffer.
- DvrPoseRingBuffer* mapped_pose_buffer_;
- // Current vsync info, updated by displayd.
- uint32_t vsync_count_;
- int64_t photon_timestamp_;
- int64_t display_period_ns_;
- int64_t right_eye_photon_offset_ns_ = 0;
-
- // To model the measurement - arrival latency.
- LatencyModel sensor_latency_;
-
- // Type for controlling pose orientation calculation.
- OrientationType device_orientation_type_;
-
- PoseService(const PoseService&) = delete;
- void operator=(const PoseService&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_POSE_SERVICE_H_
diff --git a/services/vr/sensord/sensor_fusion.cpp b/services/vr/sensord/sensor_fusion.cpp
deleted file mode 100644
index 5663ae4..0000000
--- a/services/vr/sensord/sensor_fusion.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-#include "sensor_fusion.h"
-
-#include <algorithm>
-#include <cmath>
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-// --- start of added bits for porting to eigen
-
-// In general, we prefer to add wrappers for things like Inverse() to minimize
-// the changes to the imported code, so that merging in upstream changes becomes
-// simpler.
-
-inline Matrix3d Inverse(const Matrix3d& matrix) { return matrix.inverse(); }
-inline Matrix3d Transpose(const Matrix3d& matrix) { return matrix.transpose(); }
-inline Matrix3d RotationMatrixNH(const Rotationd& rotation) {
- return rotation.toRotationMatrix();
-}
-inline double Length(const Vector3d& vector) { return vector.norm(); }
-
-using uint64 = uint64_t;
-
-// --- end of added bits for porting to eigen
-
-static const double kFiniteDifferencingEpsilon = 1e-7;
-static const double kEpsilon = 1e-15;
-// Default gyroscope frequency. This corresponds to 200 Hz.
-static const double kDefaultGyroscopeTimestep_s = 0.005f;
-// Maximum time between gyroscope before we start limiting the integration.
-static const double kMaximumGyroscopeSampleDelay_s = 0.04f;
-// Compute a first-order exponential moving average of changes in accel norm per
-// frame.
-static const double kSmoothingFactor = 0.5;
-// Minimum and maximum values used for accelerometer noise covariance matrix.
-// The smaller the sigma value, the more weight is given to the accelerometer
-// signal.
-static const double kMinAccelNoiseSigma = 0.75;
-static const double kMaxAccelNoiseSigma = 7.0;
-// Initial value for the diagonal elements of the different covariance matrices.
-static const double kInitialStateCovarianceValue = 25.0;
-static const double kInitialProcessCovarianceValue = 1.0;
-// Maximum accelerometer norm change allowed before capping it covariance to a
-// large value.
-static const double kMaxAccelNormChange = 0.15;
-// Timestep IIR filtering coefficient.
-static const double kTimestepFilterCoeff = 0.95;
-// Minimum number of sample for timestep filtering.
-static const uint32_t kTimestepFilterMinSamples = 10;
-
-// Z direction in start space.
-static const Vector3d kCanonicalZDirection(0.0, 0.0, 1.0);
-
-// Computes a axis angle rotation from the input vector.
-// angle = norm(a)
-// axis = a.normalized()
-// If norm(a) == 0, it returns an identity rotation.
-static Rotationd RotationFromVector(const Vector3d& a) {
- const double norm_a = Length(a);
- if (norm_a < kEpsilon) {
- return Rotationd::Identity();
- }
- return Rotationd(AngleAxisd(norm_a, a / norm_a));
-}
-
-// --- start of functions ported from pose_prediction.cc
-
-namespace pose_prediction {
-
-// Returns a rotation matrix based on the integration of the gyroscope_value
-// over the timestep_s in seconds.
-// TODO(pfg): Document the space better here.
-//
-// @param gyroscope_value gyroscope sensor values.
-// @param timestep_s integration period in seconds.
-// @return Integration of the gyroscope value the rotation is from Start to
-// Sensor Space.
-Rotationd GetRotationFromGyroscope(const Vector3d& gyroscope_value,
- double timestep_s) {
- const double velocity = Length(gyroscope_value);
-
- // When there is no rotation data return an identity rotation.
- if (velocity < kEpsilon) {
- return Rotationd::Identity();
- }
- // Since the gyroscope_value is a start from sensor transformation we need to
- // invert it to have a sensor from start transformation, hence the minus sign.
- // For more info:
- // http://developer.android.com/guide/topics/sensors/sensors_motion.html#sensors-motion-gyro
- return Rotationd(AngleAxisd(-timestep_s * velocity,
- gyroscope_value / velocity));
-}
-
-} // namespace pose_prediction
-
-// --- end of functions ported from pose_prediction.cc
-
-} // namespace
-
-SensorFusion::SensorFusion()
- : execute_reset_with_next_accelerometer_sample_(false) {
- ResetState();
-}
-
-void SensorFusion::Reset() {
- execute_reset_with_next_accelerometer_sample_ = true;
-}
-
-void SensorFusion::ResetState() {
- current_state_.timestamp_ns = 0;
- current_state_.sensor_from_start_rotation = Rotationd::Identity();
- current_state_.sensor_from_start_rotation_velocity = Vector3d::Zero();
-
- current_accelerometer_timestamp_ns_ = 0;
-
- state_covariance_ = Matrix3d::Identity() * kInitialStateCovarianceValue;
- process_covariance_ = Matrix3d::Identity() * kInitialProcessCovarianceValue;
- accelerometer_measurement_covariance_ =
- Matrix3d::Identity() * kMinAccelNoiseSigma * kMinAccelNoiseSigma;
- innovation_covariance_.setIdentity();
-
- accelerometer_measurement_jacobian_ = Matrix3d::Zero();
- kalman_gain_ = Matrix3d::Zero();
- innovation_ = Vector3d::Zero();
- accelerometer_measurement_ = Vector3d::Zero();
- prediction_ = Vector3d::Zero();
- control_input_ = Vector3d::Zero();
- state_update_ = Vector3d::Zero();
-
- moving_average_accelerometer_norm_change_ = 0.0;
-
- is_timestep_filter_initialized_ = false;
- is_gyroscope_filter_valid_ = false;
- is_aligned_with_gravity_ = false;
-}
-
-// Here I am doing something wrong relative to time stamps. The state timestamps
-// always correspond to the gyrostamps because it would require additional
-// extrapolation if I wanted to do otherwise.
-// TODO(pfg): investigate about published an updated pose after accelerometer
-// data was used for filtering.
-PoseState SensorFusion::GetLatestPoseState() const {
- std::unique_lock<std::mutex> lock(mutex_);
- return current_state_;
-}
-
-void SensorFusion::ProcessGyroscopeSample(float v_x, float v_y, float v_z,
- uint64 timestamp_ns) {
- std::unique_lock<std::mutex> lock(mutex_);
-
- // Don't accept gyroscope sample when waiting for a reset.
- if (execute_reset_with_next_accelerometer_sample_) {
- return;
- }
-
- // Discard outdated samples.
- if (current_state_.timestamp_ns >= timestamp_ns) {
- // TODO(pfg): Investigate why this happens.
- return;
- }
-
- // Checks that we received at least one gyroscope sample in the past.
- if (current_state_.timestamp_ns != 0) {
- // TODO(pfg): roll this in filter gyroscope timestep function.
- double current_timestep_s =
- static_cast<double>(timestamp_ns - current_state_.timestamp_ns) * 1e-9;
- if (current_timestep_s > kMaximumGyroscopeSampleDelay_s) {
- if (is_gyroscope_filter_valid_) {
- // Replaces the delta timestamp by the filtered estimates of the delta
- // time.
- current_timestep_s = filtered_gyroscope_timestep_s_;
- } else {
- current_timestep_s = kDefaultGyroscopeTimestep_s;
- }
- } else {
- FilterGyroscopeTimestep(current_timestep_s);
- }
-
- // Only integrate after receiving a accelerometer sample.
- if (is_aligned_with_gravity_) {
- const Rotationd rotation_from_gyroscope =
- pose_prediction::GetRotationFromGyroscope(Vector3d(v_x, v_y, v_z),
- current_timestep_s);
- current_state_.sensor_from_start_rotation =
- rotation_from_gyroscope * current_state_.sensor_from_start_rotation;
- current_state_.sensor_from_start_rotation.normalize();
- UpdateStateCovariance(RotationMatrixNH(rotation_from_gyroscope));
- state_covariance_ =
- state_covariance_ +
- (process_covariance_ * (current_timestep_s * current_timestep_s));
- }
- }
-
- // Saves gyroscope event for future prediction.
- current_state_.timestamp_ns = timestamp_ns;
- current_state_.sensor_from_start_rotation_velocity = Vector3d(v_x, v_y, v_z);
-}
-
-// TODO(pfg): move to rotation object for the input.
-Vector3d SensorFusion::ComputeInnovation(const Rotationd& pose) {
- const Vector3d predicted_down_direction =
- RotationMatrixNH(pose) * kCanonicalZDirection;
-
- const Rotationd rotation = Rotationd::FromTwoVectors(
- predicted_down_direction, accelerometer_measurement_);
- AngleAxisd angle_axis(rotation);
- return angle_axis.axis() * angle_axis.angle();
-}
-
-void SensorFusion::ComputeMeasurementJacobian() {
- for (int dof = 0; dof < 3; dof++) {
- // TODO(pfg): Create this delta rotation in the constructor and used unitX..
- Vector3d delta = Vector3d::Zero();
- delta[dof] = kFiniteDifferencingEpsilon;
-
- const Rotationd epsilon_rotation = RotationFromVector(delta);
- const Vector3d delta_rotation = ComputeInnovation(
- epsilon_rotation * current_state_.sensor_from_start_rotation);
-
- const Vector3d col =
- (innovation_ - delta_rotation) / kFiniteDifferencingEpsilon;
- accelerometer_measurement_jacobian_(0, dof) = col[0];
- accelerometer_measurement_jacobian_(1, dof) = col[1];
- accelerometer_measurement_jacobian_(2, dof) = col[2];
- }
-}
-
-void SensorFusion::ProcessAccelerometerSample(float acc_x, float acc_y,
- float acc_z,
- uint64 timestamp_ns) {
- std::unique_lock<std::mutex> lock(mutex_);
-
- // Discard outdated samples.
- if (current_accelerometer_timestamp_ns_ >= timestamp_ns) {
- // TODO(pfg): Investigate why this happens.
- return;
- }
-
- // Call reset state if required.
- if (execute_reset_with_next_accelerometer_sample_.exchange(false)) {
- ResetState();
- }
-
- accelerometer_measurement_ = Vector3d(acc_x, acc_y, acc_z);
- current_accelerometer_timestamp_ns_ = timestamp_ns;
-
- if (!is_aligned_with_gravity_) {
- // This is the first accelerometer measurement so it initializes the
- // orientation estimate.
- current_state_.sensor_from_start_rotation = Rotationd::FromTwoVectors(
- kCanonicalZDirection, accelerometer_measurement_);
- is_aligned_with_gravity_ = true;
-
- previous_accelerometer_norm_ = Length(accelerometer_measurement_);
- return;
- }
-
- UpdateMeasurementCovariance();
-
- innovation_ = ComputeInnovation(current_state_.sensor_from_start_rotation);
- ComputeMeasurementJacobian();
-
- // S = H * P * H' + R
- innovation_covariance_ = accelerometer_measurement_jacobian_ *
- state_covariance_ *
- Transpose(accelerometer_measurement_jacobian_) +
- accelerometer_measurement_covariance_;
-
- // K = P * H' * S^-1
- kalman_gain_ = state_covariance_ *
- Transpose(accelerometer_measurement_jacobian_) *
- Inverse(innovation_covariance_);
-
- // x_update = K*nu
- state_update_ = kalman_gain_ * innovation_;
-
- // P = (I - K * H) * P;
- state_covariance_ = (Matrix3d::Identity() -
- kalman_gain_ * accelerometer_measurement_jacobian_) *
- state_covariance_;
-
- // Updates pose and associate covariance matrix.
- const Rotationd rotation_from_state_update =
- RotationFromVector(state_update_);
-
- current_state_.sensor_from_start_rotation =
- rotation_from_state_update * current_state_.sensor_from_start_rotation;
- UpdateStateCovariance(RotationMatrixNH(rotation_from_state_update));
-}
-
-void SensorFusion::UpdateStateCovariance(const Matrix3d& motion_update) {
- state_covariance_ =
- motion_update * state_covariance_ * Transpose(motion_update);
-}
-
-void SensorFusion::FilterGyroscopeTimestep(double gyroscope_timestep_s) {
- if (!is_timestep_filter_initialized_) {
- // Initializes the filter.
- filtered_gyroscope_timestep_s_ = gyroscope_timestep_s;
- num_gyroscope_timestep_samples_ = 1;
- is_timestep_filter_initialized_ = true;
- return;
- }
-
- // Computes the IIR filter response.
- filtered_gyroscope_timestep_s_ =
- kTimestepFilterCoeff * filtered_gyroscope_timestep_s_ +
- (1 - kTimestepFilterCoeff) * gyroscope_timestep_s;
- ++num_gyroscope_timestep_samples_;
-
- if (num_gyroscope_timestep_samples_ > kTimestepFilterMinSamples) {
- is_gyroscope_filter_valid_ = true;
- }
-}
-
-void SensorFusion::UpdateMeasurementCovariance() {
- const double current_accelerometer_norm = Length(accelerometer_measurement_);
- // Norm change between current and previous accel readings.
- const double current_accelerometer_norm_change =
- std::abs(current_accelerometer_norm - previous_accelerometer_norm_);
- previous_accelerometer_norm_ = current_accelerometer_norm;
-
- moving_average_accelerometer_norm_change_ =
- kSmoothingFactor * current_accelerometer_norm_change +
- (1. - kSmoothingFactor) * moving_average_accelerometer_norm_change_;
-
- // If we hit the accel norm change threshold, we use the maximum noise sigma
- // for the accel covariance. For anything below that, we use a linear
- // combination between min and max sigma values.
- const double norm_change_ratio =
- moving_average_accelerometer_norm_change_ / kMaxAccelNormChange;
- const double accelerometer_noise_sigma = std::min(
- kMaxAccelNoiseSigma,
- kMinAccelNoiseSigma +
- norm_change_ratio * (kMaxAccelNoiseSigma - kMinAccelNoiseSigma));
-
- // Updates the accel covariance matrix with the new sigma value.
- accelerometer_measurement_covariance_ = Matrix3d::Identity() *
- accelerometer_noise_sigma *
- accelerometer_noise_sigma;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/sensor_fusion.h b/services/vr/sensord/sensor_fusion.h
deleted file mode 100644
index 0ceae21..0000000
--- a/services/vr/sensord/sensor_fusion.h
+++ /dev/null
@@ -1,181 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_SENSOR_FUSION_H_
-#define ANDROID_DVR_SENSORD_SENSOR_FUSION_H_
-
-#include <atomic>
-#include <cstdlib>
-#include <mutex>
-
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-using Matrix3d = Eigen::Matrix<double, 3, 3>;
-using Rotationd = quatd;
-using Vector3d = vec3d;
-using AngleAxisd = Eigen::AngleAxisd;
-
-// Ported from GVR's pose_state.h.
-// Stores a 3dof pose plus derivatives. This can be used for prediction.
-struct PoseState {
- // Time in nanoseconds for the current pose.
- uint64_t timestamp_ns;
-
- // Rotation from Sensor Space to Start Space.
- Rotationd sensor_from_start_rotation;
-
- // First derivative of the rotation.
- // TODO(pfg): currently storing gyro data, switch to first derivative instead.
- Vector3d sensor_from_start_rotation_velocity;
-};
-
-// Sensor fusion class that implements an Extended Kalman Filter (EKF) to
-// estimate a 3D rotation from a gyroscope and and accelerometer.
-// This system only has one state, the pose. It does not estimate any velocity
-// or acceleration.
-//
-// To learn more about Kalman filtering one can read this article which is a
-// good introduction: http://en.wikipedia.org/wiki/Kalman_filter
-//
-// Start Space is :
-// z is up.
-// y is forward based on the first sensor data.
-// x = y \times z
-// Sensor Space follows the android specification {@link
-// http://developer.android.com/guide/topics/sensors/sensors_overview.html#sensors-coords}
-// See http://go/vr-coords for definitions of Start Space and Sensor Space.
-//
-// This is a port from GVR's SensorFusion code (See
-// https://cs/vr/gvr/sensors/sensor_fusion.h)
-// which in turn is a port from java of OrientationEKF (See
-// https://cs/java/com/google/vr/cardboard/vrtoolkit/vrtoolkit/src/main/java/com/google/vrtoolkit/cardboard/sensors/internal/OrientationEKF.java)
-class SensorFusion {
- public:
- SensorFusion();
- SensorFusion(const SensorFusion&) = delete;
- void operator=(const SensorFusion&) = delete;
-
- // Resets the state of the sensor fusion. It sets the velocity for
- // prediction to zero. The reset will happen with the next
- // accelerometer sample. Gyroscope sample will be discarded until a new
- // accelerometer sample arrives.
- void Reset();
-
- // Gets the PoseState representing the latest pose and derivatives at a
- // particular timestamp as estimated by SensorFusion.
- PoseState GetLatestPoseState() const;
-
- // Processes one gyroscope sample event. This updates the pose of the system
- // and the prediction model. The gyroscope data is assumed to be in axis angle
- // form. Angle = ||v|| and Axis = v / ||v||, with v = [v_x, v_y, v_z]^T.
- //
- // @param v_x velocity in x.
- // @param v_y velocity in y.
- // @param v_z velocity in z.
- // @param timestamp_ns gyroscope event timestamp in nanosecond.
- void ProcessGyroscopeSample(float v_x, float v_y, float v_z,
- uint64_t timestamp_ns);
-
- // Processes one accelerometer sample event. This updates the pose of the
- // system. If the Accelerometer norm changes too much between sample it is not
- // trusted as much.
- //
- // @param acc_x accelerometer data in x.
- // @param acc_y accelerometer data in y.
- // @param acc_z accelerometer data in z.
- // @param timestamp_ns accelerometer event timestamp in nanosecond.
- void ProcessAccelerometerSample(float acc_x, float acc_y, float acc_z,
- uint64_t timestamp_ns);
-
- private:
- // Estimates the average timestep between gyroscope event.
- void FilterGyroscopeTimestep(double gyroscope_timestep);
-
- // Updates the state covariance with an incremental motion. It changes the
- // space of the quadric.
- void UpdateStateCovariance(const Matrix3d& motion_update);
-
- // Computes the innovation vector of the Kalman based on the input pose.
- // It uses the latest measurement vector (i.e. accelerometer data), which must
- // be set prior to calling this function.
- Vector3d ComputeInnovation(const Rotationd& pose);
-
- // This computes the measurement_jacobian_ via numerical differentiation based
- // on the current value of sensor_from_start_rotation_.
- void ComputeMeasurementJacobian();
-
- // Updates the accelerometer covariance matrix.
- //
- // This looks at the norm of recent accelerometer readings. If it has changed
- // significantly, it means the phone receives additional acceleration than
- // just gravity, and so the down vector information gravity signal is noisier.
- //
- // TODO(dcoz,pfg): this function is very simple, we probably need something
- // more elaborated here once we have proper regression testing.
- void UpdateMeasurementCovariance();
-
- // Reset all internal states. This is not thread safe. Lock should be acquired
- // outside of it. This function is called in ProcessAccelerometerSample.
- void ResetState();
-
- // Current transformation from Sensor Space to Start Space.
- // x_sensor = sensor_from_start_rotation_ * x_start;
- PoseState current_state_;
-
- // Filtering of the gyroscope timestep started?
- bool is_timestep_filter_initialized_;
- // Filtered gyroscope timestep valid?
- bool is_gyroscope_filter_valid_;
- // Sensor fusion currently aligned with gravity? After initialization
- // it will requires a couple of accelerometer data for the system to get
- // aligned.
- bool is_aligned_with_gravity_;
-
- // Covariance of Kalman filter state (P in common formulation).
- Matrix3d state_covariance_;
- // Covariance of the process noise (Q in common formulation).
- Matrix3d process_covariance_;
- // Covariance of the accelerometer measurement (R in common formulation).
- Matrix3d accelerometer_measurement_covariance_;
- // Covariance of innovation (S in common formulation).
- Matrix3d innovation_covariance_;
- // Jacobian of the measurements (H in common formulation).
- Matrix3d accelerometer_measurement_jacobian_;
- // Gain of the Kalman filter (K in common formulation).
- Matrix3d kalman_gain_;
- // Parameter update a.k.a. innovation vector. (\nu in common formulation).
- Vector3d innovation_;
- // Measurement vector (z in common formulation).
- Vector3d accelerometer_measurement_;
- // Current prediction vector (g in common formulation).
- Vector3d prediction_;
- // Control input, currently this is only the gyroscope data (\mu in common
- // formulation).
- Vector3d control_input_;
- // Update of the state vector. (x in common formulation).
- Vector3d state_update_;
-
- // Time of the last accelerometer processed event.
- uint64_t current_accelerometer_timestamp_ns_;
-
- // Estimates of the timestep between gyroscope event in seconds.
- double filtered_gyroscope_timestep_s_;
- // Number of timestep samples processed so far by the filter.
- uint32_t num_gyroscope_timestep_samples_;
- // Norm of the accelerometer for the previous measurement.
- double previous_accelerometer_norm_;
- // Moving average of the accelerometer norm changes. It is computed for every
- // sensor datum.
- double moving_average_accelerometer_norm_change_;
-
- // Flag indicating if a state reset should be executed with the next
- // accelerometer sample.
- std::atomic<bool> execute_reset_with_next_accelerometer_sample_;
-
- mutable std::mutex mutex_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_SENSOR_FUSION_H_
diff --git a/services/vr/sensord/sensor_hal_thread.cpp b/services/vr/sensord/sensor_hal_thread.cpp
deleted file mode 100644
index c321d4f..0000000
--- a/services/vr/sensord/sensor_hal_thread.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-#include "sensor_hal_thread.h"
-
-#include <dvr/performance_client_api.h>
-#include <log/log.h>
-
-namespace android {
-namespace dvr {
-
-SensorHalThread::SensorHalThread(bool* out_success)
- : shutting_down_(false),
- paused_(false),
- sensor_module_(nullptr),
- sensor_device_(nullptr),
- sensor_list_(nullptr) {
- // Assume failure; we will change this to true on success.
- *out_success = false;
-
- // TODO(segal): module & device should be singletons.
- int32_t err = hw_get_module_by_class(SENSORS_HARDWARE_MODULE_ID, "platform",
- (hw_module_t const**)&sensor_module_);
-
- if (err) {
- ALOGE("couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID,
- strerror(-err));
- return;
- }
-
- err = sensors_open_1(&sensor_module_->common, &sensor_device_);
- if (err) {
- ALOGE("couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID,
- strerror(-err));
- return;
- }
-
- const int sensor_count =
- sensor_module_->get_sensors_list(sensor_module_, &sensor_list_);
-
- // Deactivate all of the sensors initially.
- sensor_user_count_.resize(sensor_count, 0);
- for (int i = 0; i < sensor_count; ++i) {
- err = sensor_device_->activate(
- reinterpret_cast<struct sensors_poll_device_t*>(sensor_device_),
- sensor_list_[i].handle, 0);
-
- if (err) {
- ALOGE("failed to deactivate sensor %d (%s)", i, strerror(-err));
- return;
- }
- }
-
- // At this point, we've successfully initialized everything.
- *out_success = true;
-}
-
-SensorHalThread::~SensorHalThread() {
- {
- std::unique_lock<std::mutex> lock(mutex_);
- shutting_down_ = true;
- condition_.notify_one();
- }
-
- // Implicitly joins *thread_ if it's running.
-}
-
-void SensorHalThread::StartPolling(const EventConsumer& consumer) {
- if (thread_) {
- ALOGE("SensorHalThread::Start() called but thread is already running!");
- return;
- }
-
- thread_.reset(new std::thread([this, consumer] {
- const int priority_error = dvrSetSchedulerClass(0, "sensors:high");
- LOG_ALWAYS_FATAL_IF(
- priority_error < 0,
- "SensorHalTread::StartPolling: Failed to set scheduler class: %s",
- strerror(-priority_error));
-
- for (;;) {
- for (;;) {
- std::unique_lock<std::mutex> lock(mutex_);
- if (shutting_down_)
- return;
- if (!paused_)
- break;
- condition_.wait(lock);
- }
- const int kMaxEvents = 100;
- sensors_event_t events[kMaxEvents];
- ssize_t event_count = 0;
- do {
- if (sensor_device_) {
- event_count = sensor_device_->poll(
- reinterpret_cast<struct sensors_poll_device_t*>(sensor_device_),
- events, kMaxEvents);
- } else {
- // When there is no sensor_device_, we still call the consumer at
- // regular intervals in case mock poses are in use. Note that this
- // will never be the case for production devices, but this helps
- // during bringup.
- usleep(5000);
- }
- } while (event_count == -EINTR);
- if (event_count == kMaxEvents)
- ALOGI("max events (%d) reached", kMaxEvents);
-
- if (event_count >= 0) {
- consumer(events, events + event_count);
- } else {
- ALOGE(
- "SensorHalThread::StartPolling: Error while polling sensor: %s "
- "(%zd)",
- strerror(-event_count), -event_count);
- }
- }
- }));
-}
-
-void SensorHalThread::SetPaused(bool is_paused) {
- std::unique_lock<std::mutex> lock(mutex_);
- paused_ = is_paused;
- condition_.notify_one();
-}
-
-void SensorHalThread::StartUsingSensor(const int sensor_index) {
- if (sensor_index < 0 || sensor_index >= GetSensorCount()) {
- ALOGE("StartUsingSensor(): sensor index %d out of range [0, %d)",
- sensor_index, GetSensorCount());
- return;
- }
-
- std::lock_guard<std::mutex> guard(user_count_mutex_);
- if (sensor_user_count_[sensor_index]++ == 0) {
- sensor_device_->activate(
- reinterpret_cast<struct sensors_poll_device_t*>(sensor_device_),
- sensor_list_[sensor_index].handle, 1);
- sensor_device_->setDelay(
- reinterpret_cast<struct sensors_poll_device_t*>(sensor_device_),
- sensor_list_[sensor_index].handle, 0);
- }
-}
-
-void SensorHalThread::StopUsingSensor(const int sensor_index) {
- if (sensor_index < 0 || sensor_index >= GetSensorCount()) {
- ALOGE("StopUsingSensor(): sensor index %d out of range [0, %d)",
- sensor_index, GetSensorCount());
- return;
- }
-
- std::lock_guard<std::mutex> guard(user_count_mutex_);
- if (--sensor_user_count_[sensor_index] == 0) {
- sensor_device_->activate(
- reinterpret_cast<struct sensors_poll_device_t*>(sensor_device_),
- sensor_list_[sensor_index].handle, 0);
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/sensor_hal_thread.h b/services/vr/sensord/sensor_hal_thread.h
deleted file mode 100644
index 9220757..0000000
--- a/services/vr/sensord/sensor_hal_thread.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_SENSOR_HAL_THREAD_H_
-#define ANDROID_DVR_SENSORD_SENSOR_HAL_THREAD_H_
-
-#include <hardware/sensors.h>
-
-#include <atomic>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-#include "sensor_thread.h"
-
-namespace android {
-namespace dvr {
-
-// Manages initialization and polling of the sensor HAL. Polling is performed
-// continuously on a thread that passes events along to an arbitrary consumer.
-// All const member functions are thread-safe; otherwise, thread safety is noted
-// for each function.
-class SensorHalThread : public SensorThread {
- public:
- // Initializes the sensor HAL, but does not yet start polling (see Start()
- // below). Sets *out_success to true on success; otherwise, sets *out_success
- // to false and logs an error.
- explicit SensorHalThread(bool* out_success);
-
- // Tells the polling thread to shut down if it's running, and waits for it to
- // complete its polling loop.
- ~SensorHalThread() override;
-
- // Begins polling on the thread. The provided consumer will be notified of
- // events. Event notification occurs on the polling thread.
- // Calling Start() more than once on an instance of SensorHalThread is
- // invalid.
- void StartPolling(const EventConsumer& consumer) override;
-
- // Set whether the sensor polling thread is paused or not. This is useful
- // while we need to support both 3DoF and 6DoF codepaths. This 3DoF codepath
- // must be paused while the 6DoF codepath is using the IMU event stream.
- void SetPaused(bool is_paused) override;
-
- // Increase the number of users of the given sensor by one. Activates the
- // sensor if it wasn't already active.
- // Safe to call concurrently with any other functions in this class.
- void StartUsingSensor(int sensor_index) override;
-
- // Decrease the number of users of the given sensor by one. Deactivates the
- // sensor if its usage count has dropped to zero.
- // Safe to call concurrently with any other functions in this class.
- void StopUsingSensor(int sensor_index) override;
-
- // The number of sensors that are available. Returns a negative number if
- // initialization failed.
- int GetSensorCount() const override {
- return static_cast<int>(sensor_user_count_.size());
- }
-
- // The underlying sensor HAL data structure for the sensor at the given index.
- int GetSensorType(int index) const override {
- return sensor_list_[index].type;
- }
-
- private:
- // The actual thread on which we consume events.
- std::unique_ptr<std::thread> thread_;
-
- // Mutex for access to shutting_down_ and paused_ members.
- std::mutex mutex_;
-
- // Condition for signaling pause/unpause to the thread.
- std::condition_variable condition_;
-
- // If this member is set to true, the thread will stop running at its next
- // iteration. Only set with the mutex held and signal condition_ when changed.
- bool shutting_down_;
-
- // If this member is set to true, the thread will pause at its next
- // iteration. Only set with the mutex held and signal condition_ when changed.
- bool paused_;
-
- // HAL access
- struct sensors_module_t* sensor_module_;
- sensors_poll_device_1_t* sensor_device_;
-
- // Contiguous array of available sensors, owned by the sensor HAL.
- const sensor_t* sensor_list_;
-
- // Mutex that protects access to sensor_user_count_.data().
- std::mutex user_count_mutex_;
-
- // A count of how many users each sensor has. Protected by user_count_mutex.
- std::vector<int> sensor_user_count_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_SENSOR_HAL_THREAD_H_
diff --git a/services/vr/sensord/sensor_ndk_thread.cpp b/services/vr/sensord/sensor_ndk_thread.cpp
deleted file mode 100644
index 9c3abbc..0000000
--- a/services/vr/sensord/sensor_ndk_thread.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-#include "sensor_ndk_thread.h"
-
-#include <dvr/performance_client_api.h>
-#include <log/log.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-static constexpr int kLooperIdUser = 5;
-} // namespace
-
-SensorNdkThread::SensorNdkThread(bool* out_success)
- : shutting_down_(false),
- paused_(true),
- thread_started_(false),
- initialization_result_(false),
- looper_(nullptr),
- sensor_manager_(nullptr),
- event_queue_(nullptr),
- sensor_list_(nullptr),
- sensor_count_(0) {
- // Assume failure; we will change this to true on success.
- *out_success = false;
-
- // These structs are the same, but sanity check the sizes.
- static_assert(sizeof(sensors_event_t) == sizeof(ASensorEvent),
- "Error: sizeof(sensors_event_t) != sizeof(ASensorEvent)");
-
- thread_.reset(new std::thread([this] {
- const int priority_error = dvrSetSchedulerClass(0, "sensors:high");
- LOG_ALWAYS_FATAL_IF(
- priority_error < 0,
- "SensorHalTread::StartPolling: Failed to set scheduler class: %s",
- strerror(-priority_error));
-
- // Start ALooper and initialize sensor access.
- {
- std::unique_lock<std::mutex> lock(mutex_);
- InitializeSensors();
- thread_started_ = true;
- init_condition_.notify_one();
- // Continue on failure - the loop below will periodically retry.
- }
-
- EventConsumer consumer;
- for (;;) {
- for (;;) {
- std::unique_lock<std::mutex> lock(mutex_);
- UpdateSensorUse();
- if (!consumer)
- consumer = consumer_;
- if (shutting_down_)
- return;
- if (!paused_)
- break;
- condition_.wait(lock);
- }
-
- constexpr int kMaxEvents = 100;
- sensors_event_t events[kMaxEvents];
- ssize_t event_count = 0;
- if (initialization_result_) {
- int poll_fd, poll_events;
- void* poll_source;
- // Poll for events.
- int ident = ALooper_pollAll(-1, &poll_fd, &poll_events, &poll_source);
-
- if (ident != kLooperIdUser)
- continue;
-
- ASensorEvent* event = reinterpret_cast<ASensorEvent*>(&events[0]);
- event_count =
- ASensorEventQueue_getEvents(event_queue_, event, kMaxEvents);
-
- if (event_count == 0) {
- ALOGE("Detected sensor service failure, restarting sensors");
- // This happens when sensorservice has died and restarted. To avoid
- // spinning we need to restart the sensor access.
- DestroySensors();
- }
- } else {
- // When there is no sensor_device_, we still call the consumer at
- // regular intervals in case mock poses are in use. Note that this
- // will never be the case for production devices, but this helps
- // during bringup.
- usleep(5000);
- }
- if (event_count == kMaxEvents)
- ALOGI("max events (%d) reached", kMaxEvents);
-
- if (event_count >= 0) {
- consumer(events, events + event_count);
- } else {
- ALOGE(
- "SensorNdkThread::StartPolling: Error while polling sensor: %s "
- "(%zd)",
- strerror(-event_count), -event_count);
- }
- }
-
- // About to exit sensor thread, destroy sensor objects.
- DestroySensors();
- }));
-
- // Wait for thread to startup and initialize sensors so that we know whether
- // it succeeded.
- {
- std::unique_lock<std::mutex> lock(mutex_);
- while (!thread_started_)
- init_condition_.wait(lock);
- }
-
- // At this point, we've successfully initialized everything.
- // The NDK sensor thread will continue to retry on error, so assume success here.
- *out_success = true;
-}
-
-SensorNdkThread::~SensorNdkThread() {
- {
- if (looper_)
- ALooper_wake(looper_);
- std::unique_lock<std::mutex> lock(mutex_);
- shutting_down_ = true;
- condition_.notify_one();
- }
-
- thread_->join();
-}
-
-bool SensorNdkThread::InitializeSensors() {
- looper_ = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
- if (!looper_) {
- ALOGE("Failed to create ALooper.");
- return false;
- }
-
- // Prepare to monitor accelerometer
- sensor_manager_ = ASensorManager_getInstanceForPackage(nullptr);
- if (!sensor_manager_) {
- ALOGE("Failed to create ASensorManager.");
- return false;
- }
-
- event_queue_ = ASensorManager_createEventQueue(
- sensor_manager_, looper_, kLooperIdUser, nullptr, nullptr);
- if (!event_queue_) {
- ALOGE("Failed to create sensor EventQueue.");
- return false;
- }
-
- sensor_count_ = ASensorManager_getSensorList(sensor_manager_, &sensor_list_);
- ALOGI("Sensor count %d", sensor_count_);
-
- sensor_user_count_.resize(sensor_count_, 0);
-
- // To recover from sensorservice restart, enable the sensors that are already
- // requested.
- for (size_t sensor_index = 0; sensor_index < sensor_user_count_.size();
- ++sensor_index) {
- if (sensor_user_count_[sensor_index] > 0) {
- int result = ASensorEventQueue_registerSensor(
- event_queue_, sensor_list_[sensor_index], 0, 0);
- ALOGE_IF(result < 0, "ASensorEventQueue_registerSensor failed: %d",
- result);
- }
- }
-
- initialization_result_ = true;
- return true;
-}
-
-void SensorNdkThread::DestroySensors() {
- if (!event_queue_)
- return;
- for (size_t sensor_index = 0; sensor_index < sensor_user_count_.size();
- ++sensor_index) {
- if (sensor_user_count_[sensor_index] > 0) {
- ASensorEventQueue_disableSensor(event_queue_, sensor_list_[sensor_index]);
- }
- }
- ASensorManager_destroyEventQueue(sensor_manager_, event_queue_);
- event_queue_ = nullptr;
- initialization_result_ = false;
-}
-
-void SensorNdkThread::UpdateSensorUse() {
- if (!initialization_result_) {
- // Sleep for 1 second to avoid spinning during system instability.
- usleep(1000 * 1000);
- InitializeSensors();
- if (!initialization_result_)
- return;
- }
-
- if (!enable_sensors_.empty()) {
- for (int sensor_index : enable_sensors_) {
- if (sensor_user_count_[sensor_index]++ == 0) {
- int result = ASensorEventQueue_registerSensor(
- event_queue_, sensor_list_[sensor_index], 0, 0);
- ALOGE_IF(result < 0, "ASensorEventQueue_registerSensor failed: %d",
- result);
- }
- }
- enable_sensors_.clear();
- }
-
- if (!disable_sensors_.empty()) {
- for (int sensor_index : disable_sensors_) {
- if (--sensor_user_count_[sensor_index] == 0) {
- int result = ASensorEventQueue_disableSensor(
- event_queue_, sensor_list_[sensor_index]);
- ALOGE_IF(result < 0, "ASensorEventQueue_disableSensor failed: %d",
- result);
- }
- }
- disable_sensors_.clear();
- }
-}
-
-void SensorNdkThread::StartPolling(const EventConsumer& consumer) {
- {
- std::unique_lock<std::mutex> lock(mutex_);
- if (consumer_) {
- ALOGE("Already started sensor thread.");
- return;
- }
- consumer_ = consumer;
- }
- SetPaused(false);
-}
-
-void SensorNdkThread::SetPaused(bool is_paused) {
- std::unique_lock<std::mutex> lock(mutex_);
- // SetPaused may be called before we have StartPolling, make sure we have
- // an event consumer. Otherwise we defer until StartPolling is called.
- if (!consumer_)
- return;
- paused_ = is_paused;
- condition_.notify_one();
- ALooper_wake(looper_);
-}
-
-void SensorNdkThread::StartUsingSensor(const int sensor_index) {
- std::unique_lock<std::mutex> lock(mutex_);
- if (sensor_index < 0 || sensor_index >= sensor_count_) {
- ALOGE("StartUsingSensor(): sensor index %d out of range [0, %d)",
- sensor_index, sensor_count_);
- return;
- }
-
- enable_sensors_.push_back(sensor_index);
- ALooper_wake(looper_);
-}
-
-void SensorNdkThread::StopUsingSensor(const int sensor_index) {
- std::unique_lock<std::mutex> lock(mutex_);
- if (sensor_index < 0 || sensor_index >= sensor_count_) {
- ALOGE("StopUsingSensor(): sensor index %d out of range [0, %d)",
- sensor_index, sensor_count_);
- return;
- }
-
- disable_sensors_.push_back(sensor_index);
- ALooper_wake(looper_);
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/sensor_ndk_thread.h b/services/vr/sensord/sensor_ndk_thread.h
deleted file mode 100644
index eb3cf9d..0000000
--- a/services/vr/sensord/sensor_ndk_thread.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_SENSOR_NDK_THREAD_H_
-#define ANDROID_DVR_SENSORD_SENSOR_NDK_THREAD_H_
-
-#include <android/sensor.h>
-#include <hardware/sensors.h>
-
-#include <atomic>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-#include "sensor_thread.h"
-
-namespace android {
-namespace dvr {
-
-// Manages initialization and polling of the sensor data. Polling is performed
-// continuously on a thread that passes events along to an arbitrary consumer.
-// All const member functions are thread-safe; otherwise, thread safety is noted
-// for each function.
-class SensorNdkThread : public SensorThread {
- public:
- // Initializes the sensor access, but does not yet start polling (see Start()
- // below). Sets *out_success to true on success; otherwise, sets *out_success
- // to false and logs an error.
- explicit SensorNdkThread(bool* out_success);
-
- // Tells the polling thread to shut down if it's running, and waits for it to
- // complete its polling loop.
- ~SensorNdkThread() override;
-
- // Begins polling on the thread. The provided consumer will be notified of
- // events. Event notification occurs on the polling thread.
- // Calling Start() more than once on an instance of SensorNdkThread is
- // invalid.
- void StartPolling(const EventConsumer& consumer) override;
-
- // Set whether the sensor polling thread is paused or not. This is useful
- // while we need to support both 3DoF and 6DoF codepaths. This 3DoF codepath
- // must be paused while the 6DoF codepath is using the IMU event stream.
- void SetPaused(bool is_paused) override;
-
- // Increase the number of users of the given sensor by one. Activates the
- // sensor if it wasn't already active.
- // Safe to call concurrently with any other functions in this class.
- void StartUsingSensor(int sensor_index) override;
-
- // Decrease the number of users of the given sensor by one. Deactivates the
- // sensor if its usage count has dropped to zero.
- // Safe to call concurrently with any other functions in this class.
- void StopUsingSensor(int sensor_index) override;
-
- // The number of sensors that are available. Returns a negative number if
- // initialization failed.
- int GetSensorCount() const override { return sensor_count_; }
-
- // The underlying sensor HAL data structure for the sensor at the given index.
- int GetSensorType(int index) const override {
- return ASensor_getType(sensor_list_[index]);
- }
-
- private:
- // Initialize ALooper and sensor access on the thread.
- // Returns true on success, false on failure.
- bool InitializeSensors();
-
- // Destroy sensor access.
- void DestroySensors();
-
- // Start or stop requested sensors from the thread. Class mutex must already
- // be locked.
- void UpdateSensorUse();
-
- // The actual thread on which we consume events.
- std::unique_ptr<std::thread> thread_;
-
- // Mutex for access to shutting_down_ and paused_ members.
- std::mutex mutex_;
-
- // Condition for signaling pause/unpause to the thread.
- std::condition_variable condition_;
-
- // Condition for signaling thread initialization.
- std::condition_variable init_condition_;
-
- // If this member is set to true, the thread will stop running at its next
- // iteration. Only set with the mutex held and signal condition_ when changed.
- bool shutting_down_;
-
- // If this member is set to true, the thread will pause at its next
- // iteration. Only set with the mutex held and signal condition_ when changed.
- bool paused_;
-
- // Thread start hand shake to verify that sensor initialization succeeded.
- bool thread_started_;
-
- // Initialization result (true for success).
- bool initialization_result_;
-
- // The callback.
- EventConsumer consumer_;
-
- // Sensor access
- ALooper* looper_;
- ASensorManager* sensor_manager_;
- ASensorEventQueue* event_queue_;
-
- // Sensor list from NDK.
- ASensorList sensor_list_;
- int sensor_count_;
-
- // Requests to the sensor thread to enable or disable given sensors.
- std::vector<int> enable_sensors_;
- std::vector<int> disable_sensors_;
-
- // A count of how many users each sensor has. Protected by user_count_mutex.
- std::vector<int> sensor_user_count_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_SENSOR_NDK_THREAD_H_
diff --git a/services/vr/sensord/sensor_service.cpp b/services/vr/sensord/sensor_service.cpp
deleted file mode 100644
index a182a26..0000000
--- a/services/vr/sensord/sensor_service.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-#include "sensor_service.h"
-
-#include <hardware/sensors.h>
-#include <log/log.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <poll.h>
-#include <private/dvr/sensor-ipc.h>
-#include <time.h>
-
-using android::pdx::default_transport::Endpoint;
-
-namespace android {
-namespace dvr {
-
-SensorService::SensorService(SensorThread* sensor_thread)
- : BASE("SensorService", Endpoint::Create(DVR_SENSOR_SERVICE_CLIENT)),
- sensor_thread_(sensor_thread) {
- sensor_clients_.resize(sensor_thread_->GetSensorCount());
-
- for (int i = 0; i < sensor_thread_->GetSensorCount(); ++i)
- type_to_sensor_[sensor_thread_->GetSensorType(i)] = i;
-}
-
-std::shared_ptr<pdx::Channel> SensorService::OnChannelOpen(pdx::Message& msg) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- const pdx::MessageInfo& info = msg.GetInfo();
-
- std::shared_ptr<SensorClient> client(
- new SensorClient(*this, info.pid, info.cid));
- AddClient(client);
- return client;
-}
-
-void SensorService::OnChannelClose(pdx::Message& /*msg*/,
- const std::shared_ptr<pdx::Channel>& chan) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- auto client = std::static_pointer_cast<SensorClient>(chan);
- if (!client) {
- ALOGW("WARNING: SensorClient was NULL!\n");
- return;
- }
- RemoveClient(client);
-}
-
-void SensorService::AddClient(const std::shared_ptr<SensorClient>& client) {
- clients_.push_front(client);
-}
-
-void SensorService::RemoveClient(const std::shared_ptr<SensorClient>& client) {
- // First remove it from the clients associated with its sensor, if any.
- RemoveSensorClient(client.get());
-
- // Finally, remove it from the list of clients we're aware of, and decrease
- // its reference count.
- clients_.remove(client);
-}
-
-void SensorService::RemoveSensorClient(SensorClient* client) {
- if (!client->has_sensor())
- return;
-
- std::forward_list<SensorClient*>& sensor_clients =
- sensor_clients_[client->sensor()];
- sensor_clients.remove(client);
- sensor_thread_->StopUsingSensor(client->sensor());
-
- client->unset_sensor();
-}
-
-pdx::Status<void> SensorService::HandleMessage(pdx::Message& msg) {
- pdx::Status<void> ret;
- const pdx::MessageInfo& info = msg.GetInfo();
- switch (info.op) {
- case DVR_SENSOR_START: {
- std::lock_guard<std::mutex> guard(mutex_);
- // Associate this channel with the indicated sensor,
- // unless it already has an association. In that case,
- // fail.
- auto client = std::static_pointer_cast<SensorClient>(msg.GetChannel());
- if (client->has_sensor())
- REPLY_ERROR(msg, EINVAL, error);
- int sensor_type;
- if (!msg.ReadAll(&sensor_type, sizeof(sensor_type)))
- REPLY_ERROR(msg, EIO, error);
-
- // Find the sensor of the requested type.
- if (type_to_sensor_.find(sensor_type) == type_to_sensor_.end())
- REPLY_ERROR(msg, EINVAL, error);
- const int sensor_index = type_to_sensor_[sensor_type];
-
- sensor_clients_[sensor_index].push_front(client.get());
- client->set_sensor(sensor_index);
- sensor_thread_->StartUsingSensor(sensor_index);
-
- REPLY_SUCCESS(msg, 0, error);
- }
- case DVR_SENSOR_STOP: {
- std::lock_guard<std::mutex> guard(mutex_);
- auto client = std::static_pointer_cast<SensorClient>(msg.GetChannel());
- if (!client->has_sensor())
- REPLY_ERROR(msg, EINVAL, error);
- RemoveSensorClient(client.get());
- REPLY_SUCCESS(msg, 0, error);
- }
- case DVR_SENSOR_POLL: {
- std::lock_guard<std::mutex> guard(mutex_);
- auto client = std::static_pointer_cast<SensorClient>(msg.GetChannel());
-
- // Package up the events we've got for this client. Number of
- // events, followed by 0 or more sensor events, popped from
- // this client's queue until it's empty.
- int num_events = client->EventCount();
- sensors_event_t out_buffer[num_events];
- client->WriteEvents(out_buffer);
- struct iovec svec[] = {
- {.iov_base = &num_events, .iov_len = sizeof(num_events)},
- {.iov_base = out_buffer,
- .iov_len = num_events * sizeof(sensors_event_t)},
- };
- ret = msg.WriteVectorAll(svec, 2);
- if (!ret) {
- REPLY_ERROR(msg, EIO, error);
- }
- REPLY_SUCCESS(msg, 0, error);
- }
- default:
- // Do not lock mutex_ here, because this may call the on*() handlers,
- // which will lock the mutex themselves.
- ret = Service::HandleMessage(msg);
- break;
- }
-error:
- return ret;
-}
-
-void SensorService::EnqueueEvents(const sensors_event_t* begin_events,
- const sensors_event_t* end_events) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- // Put the sensor values we got in the circular queue for each client that
- // cares about the given event.
- for (const sensors_event_t* event = begin_events; event != end_events;
- ++event) {
- const int sensor_index = type_to_sensor_[event->type];
- for (const auto& client : sensor_clients_[sensor_index]) {
- client->EnqueueEvent(*event);
- }
- }
-}
-
-void SensorClient::WriteEvents(sensors_event_t* buffer) {
- while (!event_queue_.Empty()) {
- *buffer = *(event_queue_.Top());
- event_queue_.Pop();
- ++buffer;
- }
-}
-
-void SensorClient::CircularQ::Push(const sensors_event_t& event) {
- if (count_ != 0 && head_ == tail_) {
- Pop(); // If we're full, throw away the oldest event.
- }
- events_[head_] = event;
- head_ = (head_ + 1) % kCqSize;
- ++count_;
-}
-
-const sensors_event_t* SensorClient::CircularQ::Top() const {
- if (count_ == 0)
- return nullptr;
- return &events_[tail_];
-}
-
-void SensorClient::CircularQ::Pop() {
- if (count_ == 0)
- return;
- tail_ = (tail_ + 1) % kCqSize;
- --count_;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/sensor_service.h b/services/vr/sensord/sensor_service.h
deleted file mode 100644
index 6ea470b..0000000
--- a/services/vr/sensord/sensor_service.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_SENSOR_SERVICE_H_
-#define ANDROID_DVR_SENSORD_SENSOR_SERVICE_H_
-
-#include <forward_list>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/service.h>
-#include <pthread.h>
-
-#include "sensor_thread.h"
-
-namespace android {
-namespace dvr {
-
-class SensorClient;
-
-/*
- * SensorService implements the sensor service over ServiceFS.
- * The sensor service provides an interface to one sensor over
- * each channel.
- */
-class SensorService : public pdx::ServiceBase<SensorService> {
- public:
- pdx::Status<void> HandleMessage(pdx::Message& msg) override;
- std::shared_ptr<pdx::Channel> OnChannelOpen(pdx::Message& msg) override;
- void OnChannelClose(pdx::Message& msg,
- const std::shared_ptr<pdx::Channel>& chan) override;
-
- // Enqueue the events in [begin_events, end_events) onto any clients that care
- // about them.
- // Safe to call concurrently with any other public member functions.
- void EnqueueEvents(const sensors_event_t* begin_events,
- const sensors_event_t* end_events);
-
- private:
- friend BASE;
-
- // Initializes the service. Keeps a reference to sensor_thread, which must be
- // non-null.
- explicit SensorService(SensorThread* sensor_thread);
-
- // The abstraction around the sensor HAL.
- SensorThread* sensor_thread_;
-
- // All of the clients we are connected to. This is the one place in this class
- // where we keep the SensorClient instances alive using shared_ptr instances.
- std::forward_list<std::shared_ptr<SensorClient>> clients_;
-
- // Map types back to sensor indexes.
- std::unordered_map<int, int> type_to_sensor_;
- // For each sensor, the list of clients that are connected to it.
- // Every entry in here must also be in clients_, so that its reference count
- // remains positive.
- std::vector<std::forward_list<SensorClient*>> sensor_clients_;
-
- // Protects access to all member variables.
- std::mutex mutex_;
-
- // None of the following functions is thread-safe; callers must lock mutex_
- // before calling one.
- void AddClient(const std::shared_ptr<SensorClient>& client);
- void RemoveClient(const std::shared_ptr<SensorClient>& client);
- // Dissociate the indicated client from its sensor, if it has one; otherwise
- // do nothing.
- void RemoveSensorClient(SensorClient* client);
-
- SensorService(const SensorService&) = delete;
- void operator=(const SensorService&) = delete;
-};
-
-/*
- * SensorClient manages the service-side per-client context for each client
- * using the service.
- */
-class SensorClient : public pdx::Channel {
- public:
- SensorClient(SensorService& /*service*/, int /*pid*/, int /*cid*/)
- : sensor_index_(-1), has_sensor_index_(false) {}
-
- bool has_sensor() const { return has_sensor_index_; }
- int sensor() const { return sensor_index_; }
- void set_sensor(int sensor) {
- sensor_index_ = sensor;
- has_sensor_index_ = true;
- }
- void unset_sensor() {
- sensor_index_ = -1;
- has_sensor_index_ = false;
- }
-
- int EventCount() const { return event_queue_.Count(); }
-
- // Push an event onto our queue.
- void EnqueueEvent(const sensors_event_t& event) { event_queue_.Push(event); }
-
- // Write all the events in our queue (and clear it) to the supplied
- // buffer. Buffer must be large enough.
- void WriteEvents(sensors_event_t* buffer);
-
- private:
- SensorClient(const SensorClient&) = delete;
- SensorClient& operator=(const SensorClient&) = delete;
-
- int sensor_index_ = -1;
- bool has_sensor_index_ = false;
- // Circular queue holds as-yet-unasked-for events for the sensor associated
- // with this client.
- class CircularQ {
- public:
- static const int kCqSize = 10;
- CircularQ() : head_(0), tail_(0), count_(0) {}
- ~CircularQ() {}
- void Push(const sensors_event_t& event);
- const sensors_event_t* Top() const;
- void Pop();
- bool Empty() const { return count_ == 0; }
- int Count() const { return count_; }
-
- private:
- sensors_event_t events_[kCqSize];
- int head_ = 0;
- int tail_ = 0;
- int count_ = 0;
- };
- CircularQ event_queue_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_SENSOR_SERVICE_H_
diff --git a/services/vr/sensord/sensor_thread.cpp b/services/vr/sensord/sensor_thread.cpp
deleted file mode 100644
index 01e4e7e..0000000
--- a/services/vr/sensord/sensor_thread.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "sensor_thread.h"
-
-namespace android {
-namespace dvr {
-
-SensorThread::~SensorThread() {}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/sensord/sensor_thread.h b/services/vr/sensord/sensor_thread.h
deleted file mode 100644
index 46aba17..0000000
--- a/services/vr/sensord/sensor_thread.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_SENSOR_THREAD_H_
-#define ANDROID_DVR_SENSORD_SENSOR_THREAD_H_
-
-#include <hardware/sensors.h>
-
-#include <functional>
-
-namespace android {
-namespace dvr {
-
-// Manages initialization and polling of the sensor data. Polling is performed
-// continuously on a thread that passes events along to an arbitrary consumer.
-// All const member functions are thread-safe; otherwise, thread safety is noted
-// for each function.
-class SensorThread {
- public:
- // A function type that can be called to provide it with new events.
- // [events_begin, events_end) forms a contiguous array of events.
- using EventConsumer = std::function<void(const sensors_event_t* events_begin,
- const sensors_event_t* events_end)>;
-
- // Tells the polling thread to shut down if it's running, and waits for it to
- // complete its polling loop.
- virtual ~SensorThread();
-
- // Begins polling on the thread. The provided consumer will be notified of
- // events. Event notification occurs on the polling thread.
- // Calling Start() more than once on an instance of SensorThread is
- // invalid.
- virtual void StartPolling(const EventConsumer& consumer) = 0;
-
- // Set whether the sensor polling thread is paused or not. This is useful
- // while we need to support both 3DoF and 6DoF codepaths. This 3DoF codepath
- // must be paused while the 6DoF codepath is using the IMU event stream.
- virtual void SetPaused(bool is_paused) = 0;
-
- // Increase the number of users of the given sensor by one. Activates the
- // sensor if it wasn't already active.
- // Safe to call concurrently with any other functions in this class.
- virtual void StartUsingSensor(int sensor_index) = 0;
-
- // Decrease the number of users of the given sensor by one. Deactivates the
- // sensor if its usage count has dropped to zero.
- // Safe to call concurrently with any other functions in this class.
- virtual void StopUsingSensor(int sensor_index) = 0;
-
- // The number of sensors that are available. Returns a negative number if
- // initialization failed.
- virtual int GetSensorCount() const = 0;
-
- // Get the sensor type for the sensor at the given index.
- virtual int GetSensorType(int index) const = 0;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_SENSOR_THREAD_H_
diff --git a/services/vr/sensord/sensord.cpp b/services/vr/sensord/sensord.cpp
deleted file mode 100644
index db39152..0000000
--- a/services/vr/sensord/sensord.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#define LOG_TAG "sensord"
-
-#include <string.h>
-
-#include <binder/ProcessState.h>
-
-#include <dvr/performance_client_api.h>
-#include <pdx/default_transport/service_dispatcher.h>
-#include <private/dvr/pose-ipc.h>
-#include <private/dvr/sensor-ipc.h>
-
-#include "pose_service.h"
-#include "sensor_hal_thread.h"
-#include "sensor_ndk_thread.h"
-#include "sensor_service.h"
-#include "sensor_thread.h"
-#include "sensord_extension.h"
-
-using android::dvr::PoseService;
-using android::dvr::SensorHalThread;
-using android::dvr::SensorNdkThread;
-using android::dvr::SensorService;
-using android::dvr::SensorThread;
-using android::pdx::Service;
-using android::pdx::ServiceDispatcher;
-using android::dvr::SensordExtension;
-
-int main(int, char**) {
- ALOGI("Starting up...");
-
- SensordExtension::run();
-
- // We need to be able to create endpoints with full perms.
- umask(0000);
-
- android::ProcessState::self()->startThreadPool();
-
- bool sensor_thread_succeeded = false;
-#ifdef SENSORD_USES_HAL
- std::unique_ptr<SensorThread> sensor_thread(
- new SensorHalThread(&sensor_thread_succeeded));
-#else
- std::unique_ptr<SensorThread> sensor_thread(
- new SensorNdkThread(&sensor_thread_succeeded));
-#endif
-
- if (!sensor_thread_succeeded) {
- ALOGE("ERROR: Failed to initialize SensorThread! No 3DoF!\n");
- }
-
- if (sensor_thread->GetSensorCount() == 0)
- ALOGW("No sensors found\n");
-
- auto sensor_service = SensorService::Create(sensor_thread.get());
- if (!sensor_service) {
- ALOGE("TERMINATING: failed to create SensorService!!!\n");
- return -1;
- }
-
- auto pose_service = PoseService::Create(sensor_thread.get());
- if (!pose_service) {
- ALOGE("TERMINATING: failed to create PoseService!!!\n");
- return -1;
- }
-
- std::unique_ptr<ServiceDispatcher> dispatcher =
- android::pdx::default_transport::ServiceDispatcher::Create();
- if (!dispatcher) {
- ALOGE("TERMINATING: failed to create ServiceDispatcher!!!\n");
- return -1;
- }
-
- dispatcher->AddService(sensor_service);
- dispatcher->AddService(pose_service);
-
- sensor_thread->StartPolling([sensor_service, pose_service](
- const sensors_event_t* events_begin, const sensors_event_t* events_end) {
- sensor_service->EnqueueEvents(events_begin, events_end);
- pose_service->HandleEvents(events_begin, events_end);
- });
-
- const int priority_error = dvrSetSchedulerClass(0, "sensors:low");
- LOG_ALWAYS_FATAL_IF(priority_error < 0,
- "SensorService: Failed to set scheduler class: %s",
- strerror(-priority_error));
-
- int ret = dispatcher->EnterDispatchLoop();
- ALOGI("Dispatch loop exited because: %s\n", strerror(-ret));
-
- return ret;
-}
diff --git a/services/vr/sensord/sensord.rc b/services/vr/sensord/sensord.rc
deleted file mode 100644
index 36cd377..0000000
--- a/services/vr/sensord/sensord.rc
+++ /dev/null
@@ -1,11 +0,0 @@
-on init
- mkdir /dev/socket/pdx/system/vr/pose 0775 system system
- mkdir /dev/socket/pdx/system/vr/sensors 0775 system system
-
-service sensord /system/bin/sensord
- class core
- user system
- group system camera sdcard_rw
- writepid /dev/cpuset/system/tasks
- socket pdx/system/vr/sensors/client stream 0666 system system
- socket pdx/system/vr/pose/client stream 0666 system system
diff --git a/services/vr/sensord/sensord_extension.cpp b/services/vr/sensord/sensord_extension.cpp
deleted file mode 100644
index 6cd7db3..0000000
--- a/services/vr/sensord/sensord_extension.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "sensord_extension.h"
-
-void android::dvr::SensordExtension::run() {
-}
diff --git a/services/vr/sensord/sensord_extension.h b/services/vr/sensord/sensord_extension.h
deleted file mode 100644
index e553eed..0000000
--- a/services/vr/sensord/sensord_extension.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef ANDROID_DVR_SENSORD_EXTENSION_H_
-#define ANDROID_DVR_SENSORD_EXTENSION_H_
-
-namespace android {
-namespace dvr {
-
-// Allows sensord to be extended with additional code.
-class SensordExtension {
- public:
- static void run();
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSORD_EXTENSION_H_
diff --git a/services/vr/sensord/test/poselatencytest.cpp b/services/vr/sensord/test/poselatencytest.cpp
deleted file mode 100644
index 615fc75..0000000
--- a/services/vr/sensord/test/poselatencytest.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <dvr/pose_client.h>
-#include <inttypes.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <vector>
-
-// Creates a pose client and polls 30x for new data. Prints timestamp and
-// latency. Latency is calculated based on the difference between the
-// current clock and the timestamp from the Myriad, which has been synced
-// to QC time. Note that there is some clock drift and clocks are only sycned
-// when the FW is loaded.
-int main(int /*argc*/, char** /*argv*/) {
- DvrPose* pose_client = dvrPoseCreate();
- if (pose_client == nullptr) {
- printf("Unable to create pose client\n");
- return -1;
- }
-
- DvrPoseAsync last_state;
- DvrPoseAsync current_state;
- last_state.timestamp_ns = 0;
- current_state.timestamp_ns = 0;
-
- double avg_latency = 0;
- double min_latency = (float)UINT64_MAX;
- double max_latency = 0;
- double std = 0;
- std::vector<uint64_t> latency;
-
- int num_samples = 100;
- for (int i = 0; i < num_samples; ++i) {
- while (last_state.timestamp_ns == current_state.timestamp_ns) {
- uint32_t vsync_count = dvrPoseGetVsyncCount(pose_client);
- int err = dvrPoseGet(pose_client, vsync_count, ¤t_state);
- if (err) {
- printf("Error polling pose: %d\n", err);
- dvrPoseDestroy(pose_client);
- return err;
- }
- }
- struct timespec timespec;
- uint64_t timestamp, diff;
- clock_gettime(CLOCK_MONOTONIC, ×pec);
- timestamp =
- ((uint64_t)timespec.tv_sec * 1000000000) + (uint64_t)timespec.tv_nsec;
- if (timestamp < current_state.timestamp_ns) {
- printf("ERROR: excessive clock drift detected, reload FW to resync\n");
- return -1;
- }
- diff = timestamp - current_state.timestamp_ns;
- printf("%02d) ts = %" PRIu64 " time = %" PRIu64 "\n", i + 1,
- current_state.timestamp_ns, timestamp);
- printf("\tlatency: %" PRIu64 " ns (%" PRIu64 " us) (%" PRIu64 " ms)\n",
- diff, diff / 1000, diff / 1000000);
-
- avg_latency += diff;
- if (diff < min_latency) {
- min_latency = diff;
- }
- if (diff > max_latency) {
- max_latency = diff;
- }
- latency.push_back(diff);
-
- last_state = current_state;
- }
- avg_latency /= num_samples;
- for (unsigned int i = 0; i < latency.size(); i++) {
- std += pow(latency[i] - avg_latency, 2);
- }
- std /= latency.size();
- std = sqrt(std);
-
- printf("\n************************\n");
- printf("Avg latency = %lf ns (%lf us) (%lf ms)\n", avg_latency,
- avg_latency / 1000, avg_latency / 1000000);
- printf("Max latency = %lf ns (%lf us) (%lf ms)\n", max_latency,
- max_latency / 1000, max_latency / 1000000);
- printf("Min latency = %lf ns (%lf us) (%lf ms)\n", min_latency,
- min_latency / 1000, min_latency / 1000000);
- printf("Standard dev = %lf ns (%lf us) (%lf ms)\n", std, std / 1000,
- std / 1000000);
- printf("\n************************\n");
- return 0;
-}