Fix enforcement of sensor's slowest rate am: 663720b29f
am: 6528410dbd
Change-Id: I3026783f4b9442d59939b2e2bf1755971a517b15
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/pose.cpp b/cmds/vr/pose/pose.cpp
index 2288a86..faceb67 100644
--- a/cmds/vr/pose/pose.cpp
+++ b/cmds/vr/pose/pose.cpp
@@ -28,7 +28,7 @@
" 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"
+ "circle_strafe, float, motion_sickness.\n"
<< " --unfreeze: sets the mode to normal.\n"
<< " --log_controller=[true|false]: starts and stops controller"
" logs\n"
@@ -150,6 +150,12 @@
} else if (value == "circle_strafe") {
*mode = DVR_POSE_MODE_MOCK_CIRCLE_STRAFE;
return true;
+ } else if (value == "float") {
+ *mode = DVR_POSE_MODE_FLOAT;
+ return true;
+ } else if (value == "motion_sickness") {
+ *mode = DVR_POSE_MODE_MOCK_MOTION_SICKNESS;
+ return true;
} else {
return false;
}
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/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..7c4bdf9 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,55 @@
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;
+ }
+ }
+ }
+ dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
+ }
+ return true;
+}
+
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window,
const EGLint *attrib_list)
@@ -502,7 +552,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 +590,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 +623,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 +643,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 +669,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 +720,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 +1763,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/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/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/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/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/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 45cac6f..1456429 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2641,6 +2641,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) {
@@ -3206,6 +3208,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/pose_service.cpp b/services/vr/sensord/pose_service.cpp
index 75423bb..edf4998 100644
--- a/services/vr/sensord/pose_service.cpp
+++ b/services/vr/sensord/pose_service.cpp
@@ -93,6 +93,10 @@
return "DVR_POSE_MODE_MOCK_ROTATE_FAST";
case DVR_POSE_MODE_MOCK_CIRCLE_STRAFE:
return "DVR_POSE_MODE_MOCK_CIRCLE_STRAFE";
+ case DVR_POSE_MODE_FLOAT:
+ return "DVR_POSE_MODE_FLOAT";
+ case DVR_POSE_MODE_MOCK_MOTION_SICKNESS:
+ return "DVR_POSE_MODE_MOCK_MOTION_SICKNESS";
default:
return "Unknown pose mode";
}
@@ -421,7 +425,8 @@
current_time_ns);
break;
}
- case DVR_POSE_MODE_3DOF: {
+ case DVR_POSE_MODE_3DOF:
+ case DVR_POSE_MODE_FLOAT: {
// Sensor fusion provides IMU-space data, transform to world space.
// Constants to perform IMU orientation adjustments. Note that these
@@ -458,13 +463,25 @@
}
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);
+ Vector3d position;
+ switch (pose_mode_) {
+ default:
+ case DVR_POSE_MODE_3DOF:
+ // 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).
+ position = start_from_head_rotation *
+ Vector3d(0.0, kDefaultNeckVerticalOffset,
+ -kDefaultNeckHorizontalOffset);
+ break;
+ case DVR_POSE_MODE_FLOAT:
+ // Change position a bit in facing direction.
+ mock_pos_offset_ += start_from_head_rotation.toRotationMatrix() * Vector3d(0, 0, -0.01);
+ ResetMockDeviatedPosition();
+ position = mock_pos_offset_;
+ break;
+ }
// Update the current latency model.
if (pose_state.timestamp_ns != 0) {
@@ -478,6 +495,26 @@
pose_state.timestamp_ns + sensor_latency_.CurrentLatencyEstimate());
break;
}
+ case DVR_POSE_MODE_MOCK_MOTION_SICKNESS: {
+ double phase = std::sin(current_time_ns / 1e9) + 1;
+ // Randomize 3rd order rotation axis on phase minimum.
+ if (phase > mock_prev_phase_ && mock_diff_phase_ < 0)
+ mock_rot_axis_2_ = RandVector();
+ mock_diff_phase_ = phase - mock_prev_phase_;
+ mock_prev_phase_ = phase;
+
+ // Rotate axes all the way down.
+ mock_rot_axis_2_ = AngleAxisd(0.004 * phase, mock_rot_axis_3_) * mock_rot_axis_2_;
+ mock_rot_axis_1_ = AngleAxisd(0.002 * (std::sin(current_time_ns / 5e8 + M_PI / 2) + 1), mock_rot_axis_2_) * mock_rot_axis_1_;
+ Rotationd rotation = Rotationd(AngleAxisd(fmod(current_time_ns / 2e9, kTwoPi), mock_rot_axis_1_));
+
+ // Change position a bit.
+ mock_pos_offset_ += rotation.toRotationMatrix() * Vector3d(0, 0, 0.003 * (std::sin(current_time_ns / 6e8) + 1));
+ ResetMockDeviatedPosition();
+
+ WriteAsyncPoses(mock_pos_offset_, rotation, current_time_ns);
+ break;
+ }
default:
case DVR_POSE_MODE_6DOF:
ALOGE("ERROR: invalid pose mode");
@@ -485,6 +522,13 @@
}
}
+void PoseService::ResetMockDeviatedPosition() {
+ if (mock_pos_offset_[1] < -1) mock_pos_offset_[1] = 2;
+ if (mock_pos_offset_[1] > 30) mock_pos_offset_[1] = 2;
+ if (abs(mock_pos_offset_[0]) > 30) mock_pos_offset_[0] = mock_pos_offset_[2] = 0;
+ if (abs(mock_pos_offset_[2]) > 30) mock_pos_offset_[0] = mock_pos_offset_[2] = 0;
+}
+
pdx::Status<void> PoseService::HandleMessage(pdx::Message& msg) {
pdx::Status<void> ret;
const pdx::MessageInfo& info = msg.GetInfo();
@@ -638,6 +682,10 @@
if (mode == DVR_POSE_MODE_6DOF) {
// Only 3DoF is currently supported.
mode = DVR_POSE_MODE_3DOF;
+ } else if (mode == DVR_POSE_MODE_MOCK_MOTION_SICKNESS) {
+ mock_rot_axis_1_ = RandVector();
+ mock_rot_axis_2_ = RandVector();
+ mock_rot_axis_3_ = RandVector();
}
pose_mode_ = mode;
diff --git a/services/vr/sensord/pose_service.h b/services/vr/sensord/pose_service.h
index 7b7adec..acf4124 100644
--- a/services/vr/sensord/pose_service.h
+++ b/services/vr/sensord/pose_service.h
@@ -102,6 +102,25 @@
// Last known pose.
DvrPoseAsync last_known_pose_;
+ // Position offset for use in pose modes.
+ Eigen::Vector3d mock_pos_offset_;
+
+ // Phase data for DVR_POSE_MODE_MOCK_MOTION_SICKNESS.
+ double mock_prev_phase_, mock_diff_phase_;
+
+ // Axis data for DVR_POSE_MODE_MOCK_MOTION_SICKNESS.
+ Eigen::Vector3d mock_rot_axis_1_, mock_rot_axis_2_, mock_rot_axis_3_;
+
+ // Return a random normalized 3d vector.
+ static Eigen::Vector3d RandVector() {
+ Eigen::Vector3d vec = Eigen::Vector3d::Random();
+ vec.normalize();
+ return vec;
+ }
+
+ // Reset mock_pos_offset_ if strayed too far
+ void ResetMockDeviatedPosition();
+
// 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_;