Merge "Change mLayersWithQueuedFrames to be an unordered_set"
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index 2618906..b1bc6dc 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -130,7 +130,7 @@
}
IPCThreadState::self()->setTheContextObject(manager);
- ps->becomeContextManager(nullptr, nullptr);
+ ps->becomeContextManager();
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
diff --git a/include/android/sharedmem.h b/include/android/sharedmem.h
index 6efa4f7..5f74682 100644
--- a/include/android/sharedmem.h
+++ b/include/android/sharedmem.h
@@ -65,6 +65,10 @@
* another process. File descriptors may also be sent to other processes over a Unix domain
* socket with sendmsg and SCM_RIGHTS. See sendmsg(3) and cmsg(3) man pages for more information.
*
+ * If you intend to share this file descriptor with a child process after
+ * calling exec(3), note that you will need to use fcntl(2) with FD_SETFD
+ * to clear the FD_CLOEXEC flag for this to work on all versions of Android.
+ *
* Available since API level 26.
*
* \param name an optional name.
diff --git a/include/attestation/HmacKeyManager.h b/include/attestation/HmacKeyManager.h
new file mode 100644
index 0000000..571a361
--- /dev/null
+++ b/include/attestation/HmacKeyManager.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <array>
+
+namespace android {
+/**
+ * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified.
+ */
+constexpr std::array<uint8_t, 32> INVALID_HMAC = {0};
+
+class HmacKeyManager {
+public:
+ HmacKeyManager();
+ std::array<uint8_t, 32> sign(const uint8_t* data, size_t size) const;
+private:
+ const std::array<uint8_t, 128> mHmacKey;
+};
+} // namespace android
\ No newline at end of file
diff --git a/include/input/Input.h b/include/input/Input.h
index d40ba43..7b66d3c 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -312,11 +312,6 @@
*/
constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN();
-/**
- * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified.
- */
-constexpr std::array<uint8_t, 32> INVALID_HMAC = {0};
-
/*
* Pointer coordinate data.
*/
diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h
index 2ae4fd5..08ad8c6 100644
--- a/include/input/Keyboard.h
+++ b/include/input/Keyboard.h
@@ -20,8 +20,8 @@
#include <input/Input.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
+#include <input/PropertyMap.h>
#include <utils/Errors.h>
-#include <utils/PropertyMap.h>
namespace android {
diff --git a/include/input/PropertyMap.h b/include/input/PropertyMap.h
new file mode 100644
index 0000000..3d04331
--- /dev/null
+++ b/include/input/PropertyMap.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UTILS_PROPERTY_MAP_H
+#define _UTILS_PROPERTY_MAP_H
+
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/Tokenizer.h>
+
+namespace android {
+
+/*
+ * Provides a mechanism for passing around string-based property key / value pairs
+ * and loading them from property files.
+ *
+ * The property files have the following simple structure:
+ *
+ * # Comment
+ * key = value
+ *
+ * Keys and values are any sequence of printable ASCII characters.
+ * The '=' separates the key from the value.
+ * The key and value may not contain whitespace.
+ *
+ * The '\' character is reserved for escape sequences and is not currently supported.
+ * The '"" character is reserved for quoting and is not currently supported.
+ * Files that contain the '\' or '"' character will fail to parse.
+ *
+ * The file must not contain duplicate keys.
+ *
+ * TODO Support escape sequences and quoted values when needed.
+ */
+class PropertyMap {
+public:
+ /* Creates an empty property map. */
+ PropertyMap();
+ ~PropertyMap();
+
+ /* Clears the property map. */
+ void clear();
+
+ /* Adds a property.
+ * Replaces the property with the same key if it is already present.
+ */
+ void addProperty(const String8& key, const String8& value);
+
+ /* Returns true if the property map contains the specified key. */
+ bool hasProperty(const String8& key) const;
+
+ /* Gets the value of a property and parses it.
+ * Returns true and sets outValue if the key was found and its value was parsed successfully.
+ * Otherwise returns false and does not modify outValue. (Also logs a warning.)
+ */
+ bool tryGetProperty(const String8& key, String8& outValue) const;
+ bool tryGetProperty(const String8& key, bool& outValue) const;
+ bool tryGetProperty(const String8& key, int32_t& outValue) const;
+ bool tryGetProperty(const String8& key, float& outValue) const;
+
+ /* Adds all values from the specified property map. */
+ void addAll(const PropertyMap* map);
+
+ /* Gets the underlying property map. */
+ inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }
+
+ /* Loads a property map from a file. */
+ static status_t load(const String8& filename, PropertyMap** outMap);
+
+private:
+ class Parser {
+ PropertyMap* mMap;
+ Tokenizer* mTokenizer;
+
+ public:
+ Parser(PropertyMap* map, Tokenizer* tokenizer);
+ ~Parser();
+ status_t parse();
+
+ private:
+ status_t parseType();
+ status_t parseKey();
+ status_t parseKeyProperty();
+ status_t parseModifier(const String8& token, int32_t* outMetaState);
+ status_t parseCharacterLiteral(char16_t* outCharacter);
+ };
+
+ KeyedVector<String8, String8> mProperties;
+};
+
+} // namespace android
+
+#endif // _UTILS_PROPERTY_MAP_H
diff --git a/libs/attestation/Android.bp b/libs/attestation/Android.bp
new file mode 100644
index 0000000..b85aecd
--- /dev/null
+++ b/libs/attestation/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+cc_library_static {
+ name: "libattestation",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ srcs: [
+ "HmacKeyManager.cpp"
+ ],
+
+ clang: true,
+
+ shared_libs: [
+ "liblog",
+ "libcrypto",
+ ],
+}
\ No newline at end of file
diff --git a/libs/attestation/HmacKeyManager.cpp b/libs/attestation/HmacKeyManager.cpp
new file mode 100644
index 0000000..b15f143
--- /dev/null
+++ b/libs/attestation/HmacKeyManager.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <attestation/HmacKeyManager.h>
+#include <log/log.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+
+namespace android {
+
+static std::array<uint8_t, 128> getRandomKey() {
+ std::array<uint8_t, 128> key;
+ if (RAND_bytes(key.data(), key.size()) != 1) {
+ LOG_ALWAYS_FATAL("Can't generate HMAC key");
+ }
+ return key;
+}
+
+HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {}
+
+std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const {
+ // SHA256 always generates 32-bytes result
+ std::array<uint8_t, 32> hash;
+ unsigned int hashLen = 0;
+ uint8_t* result =
+ HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen);
+ if (result == nullptr) {
+ ALOGE("Could not sign the data using HMAC");
+ return INVALID_HMAC;
+ }
+
+ if (hashLen != hash.size()) {
+ ALOGE("HMAC-SHA256 has unexpected length");
+ return INVALID_HMAC;
+ }
+
+ return hash;
+}
+} // namespace android
\ No newline at end of file
diff --git a/libs/attestation/OWNERS b/libs/attestation/OWNERS
new file mode 100644
index 0000000..4dbb0ea
--- /dev/null
+++ b/libs/attestation/OWNERS
@@ -0,0 +1,2 @@
+chaviw@google.com
+svv@google.com
\ No newline at end of file
diff --git a/libs/attestation/TEST_MAPPING b/libs/attestation/TEST_MAPPING
new file mode 100644
index 0000000..43be638
--- /dev/null
+++ b/libs/attestation/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "libattestation_tests"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/libs/attestation/tests/Android.bp b/libs/attestation/tests/Android.bp
new file mode 100644
index 0000000..6ce5ea1
--- /dev/null
+++ b/libs/attestation/tests/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+ name: "libattestation_tests",
+ test_suites: ["device-tests"],
+ srcs: [
+ "HmacKeyManager_test.cpp",
+ ],
+ static_libs: [
+ "libattestation",
+ ],
+ shared_libs: [
+ "liblog",
+ "libcrypto",
+ ],
+}
diff --git a/libs/attestation/tests/HmacKeyManager_test.cpp b/libs/attestation/tests/HmacKeyManager_test.cpp
new file mode 100644
index 0000000..7f7a408
--- /dev/null
+++ b/libs/attestation/tests/HmacKeyManager_test.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <attestation/HmacKeyManager.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+class HmacKeyManagerTest : public testing::Test {
+protected:
+ HmacKeyManager mHmacKeyManager;
+};
+
+/**
+ * Ensure that separate calls to sign the same data are generating the same key.
+ * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
+ * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
+ * tests.
+ */
+TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) {
+ std::array<uint8_t, 10> data = {4, 3, 5, 1, 8, 5, 2, 7, 1, 8};
+
+ std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(data.data(), sizeof(data));
+ std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(data.data(), sizeof(data));
+ ASSERT_EQ(hmac1, hmac2);
+}
+
+/**
+ * Ensure that changes in the hmac verification data produce a different hmac.
+ */
+TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) {
+ std::array<uint8_t, 10> data = {4, 3, 5, 1, 8, 5, 2, 7, 1, 8};
+ std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(data.data(), sizeof(data));
+
+ data[2] = 2;
+ ASSERT_NE(initialHmac, mHmacKeyManager.sign(data.data(), sizeof(data)));
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 157538e..9aaca65 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -679,7 +679,7 @@
CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
ANDROID_LOG_ERROR);
} else /* FATAL_IF_NOT_ONEWAY */ {
- LOG_ALWAYS_FATAL("Process may not make oneway calls (code: %u).", code);
+ LOG_ALWAYS_FATAL("Process may not make non-oneway calls (code: %u).", code);
}
}
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index ef93ba1..a530565 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -144,11 +144,9 @@
}
}
-bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
+bool ProcessState::becomeContextManager()
{
AutoMutex _l(mLock);
- mBinderContextCheckFunc = checkFunc;
- mBinderContextUserData = userData;
flat_binder_object obj {
.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
@@ -165,8 +163,6 @@
}
if (result == -1) {
- mBinderContextCheckFunc = nullptr;
- mBinderContextUserData = nullptr;
ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
}
@@ -397,8 +393,6 @@
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
- , mBinderContextCheckFunc(nullptr)
- , mBinderContextUserData(nullptr)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
, mCallRestriction(CallRestriction::NONE)
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 9f5346a..efb95f4 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -50,14 +50,8 @@
sp<IBinder> getContextObject(const sp<IBinder>& caller);
void startThreadPool();
-
- typedef bool (*context_check_func)(const String16& name,
- const sp<IBinder>& caller,
- void* userData);
- bool becomeContextManager(
- context_check_func checkFunc,
- void* userData);
+ bool becomeContextManager();
sp<IBinder> getStrongProxyForHandle(int32_t handle);
void expungeHandle(int32_t handle, IBinder* binder);
@@ -128,9 +122,6 @@
Vector<handle_entry>mHandleToObject;
- context_check_func mBinderContextCheckFunc;
- void* mBinderContextUserData;
-
String8 mRootDir;
bool mThreadPoolStarted;
volatile int32_t mThreadPoolSeq;
diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
index d4feaba..5811760 100644
--- a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
@@ -32,7 +32,8 @@
*
* \param binder local server binder to request security contexts on
*/
-void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCED_IN(31);
+__attribute__((weak)) void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid)
+ __INTRODUCED_IN(31);
/**
* Returns the selinux context of the callee.
@@ -45,7 +46,7 @@
* \return security context or null if unavailable. The lifetime of this context
* is the lifetime of the transaction.
*/
-__attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
+__attribute__((weak, warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 52bcd20..2784aa8 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -29,9 +29,9 @@
* \param binder object to register globally with the service manager.
* \param instance identifier of the service. This will be used to lookup the service.
*
- * \return STATUS_OK on success.
+ * \return EX_NONE on success.
*/
-binder_status_t AServiceManager_addService(AIBinder* binder, const char* instance);
+binder_exception_t AServiceManager_addService(AIBinder* binder, const char* instance);
/**
* Gets a binder object with this specific instance name. Will return nullptr immediately if the
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 6b2184e..c782d47 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -29,14 +29,14 @@
using ::android::status_t;
using ::android::String16;
-binder_status_t AServiceManager_addService(AIBinder* binder, const char* instance) {
+binder_exception_t AServiceManager_addService(AIBinder* binder, const char* instance) {
if (binder == nullptr || instance == nullptr) {
- return STATUS_UNEXPECTED_NULL;
+ return EX_ILLEGAL_ARGUMENT;
}
sp<IServiceManager> sm = defaultServiceManager();
- status_t status = sm->addService(String16(instance), binder->getBinder());
- return PruneStatusT(status);
+ status_t exception = sm->addService(String16(instance), binder->getBinder());
+ return PruneException(exception);
}
AIBinder* AServiceManager_checkService(const char* instance) {
if (instance == nullptr) {
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index 87e1341..d889593 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -123,8 +123,8 @@
return STATUS_UNKNOWN_ERROR;
default:
- LOG(WARNING) << __func__
- << ": Unknown status_t pruned into STATUS_UNKNOWN_ERROR: " << status;
+ LOG(WARNING) << __func__ << ": Unknown status_t (" << status
+ << ") pruned into STATUS_UNKNOWN_ERROR";
return STATUS_UNKNOWN_ERROR;
}
}
@@ -155,8 +155,8 @@
return EX_TRANSACTION_FAILED;
default:
- LOG(WARNING) << __func__
- << ": Unknown status_t pruned into EX_TRANSACTION_FAILED: " << exception;
+ LOG(WARNING) << __func__ << ": Unknown binder exception (" << exception
+ << ") pruned into EX_TRANSACTION_FAILED";
return EX_TRANSACTION_FAILED;
}
}
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index 7c271f6..46e6270 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -66,9 +66,6 @@
],
test_suites: ["general-tests", "vts"],
require_root: true,
-
- // force since binderVendorDoubleLoadTest has its own
- auto_gen_config: true,
}
cc_test {
@@ -90,6 +87,7 @@
"libutils",
],
test_suites: ["general-tests", "vts"],
+ require_root: true,
}
aidl_interface {
diff --git a/libs/binder/ndk/tests/AndroidTest.xml b/libs/binder/ndk/tests/AndroidTest.xml
deleted file mode 100644
index 89646f7..0000000
--- a/libs/binder/ndk/tests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Runs binderVendorDoubleLoadTest.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
-
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="binderVendorDoubleLoadTest->/data/nativetest/vendor/binderVendorDoubleLoadTest" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/nativetest/vendor" />
- <option name="module-name" value="binderVendorDoubleLoadTest" />
- </test>
-</configuration>
-
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 1424b6c..2bd5248 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -84,10 +84,11 @@
AIBinder_setRequestingSid(binder.get(), true);
- binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
+ binder_exception_t exception =
+ AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
- if (status != STATUS_OK) {
- LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
+ if (exception != EX_NONE) {
+ LOG(FATAL) << "Could not register: " << exception << " " << kBinderNdkUnitTestService;
}
ABinderProcess_joinThreadPool();
@@ -111,10 +112,10 @@
void manualService(const char* instance) {
// Strong reference to MyFoo kept by service manager.
- binder_status_t status = (new MyFoo)->addService(instance);
+ binder_exception_t exception = (new MyFoo)->addService(instance);
- if (status != STATUS_OK) {
- LOG(FATAL) << "Could not register: " << status << " " << instance;
+ if (exception != EX_NONE) {
+ LOG(FATAL) << "Could not register: " << exception << " " << instance;
}
}
int manualPollingService(const char* instance) {
@@ -322,11 +323,20 @@
}
};
+TEST(NdkBinder, AddNullService) {
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, AServiceManager_addService(nullptr, "any-service-name"));
+}
+
+TEST(NdkBinder, AddInvalidServiceName) {
+ sp<IFoo> foo = new MyTestFoo;
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, foo->addService("!@#$%^&"));
+}
+
TEST(NdkBinder, GetServiceInProcess) {
static const char* kInstanceName = "test-get-service-in-process";
sp<IFoo> foo = new MyTestFoo;
- EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName));
+ EXPECT_EQ(EX_NONE, foo->addService(kInstanceName));
sp<IFoo> getFoo = IFoo::getService(kInstanceName);
EXPECT_EQ(foo.get(), getFoo.get());
@@ -373,8 +383,8 @@
static const char* kInstanceName1 = "test-multi-1";
static const char* kInstanceName2 = "test-multi-2";
sp<IFoo> foo = new MyTestFoo;
- EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName1));
- EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
+ EXPECT_EQ(EX_NONE, foo->addService(kInstanceName1));
+ EXPECT_EQ(EX_NONE, foo->addService(kInstanceName2));
EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
}
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 9285b23..ae265ca 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -55,7 +55,6 @@
"DisplayEventDispatcher.cpp",
"DisplayEventReceiver.cpp",
"GLConsumer.cpp",
- "GuiConfig.cpp",
"IConsumerListener.cpp",
"IDisplayEventConnection.cpp",
"IGraphicBufferConsumer.cpp",
diff --git a/libs/gui/GuiConfig.cpp b/libs/gui/GuiConfig.cpp
deleted file mode 100644
index 3ec20ee..0000000
--- a/libs/gui/GuiConfig.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gui/GuiConfig.h>
-
-namespace android {
-
-void appendGuiConfigString(std::string& configStr) {
- static const char* config =
- " [libgui"
-#ifdef DONT_USE_FENCE_SYNC
- " DONT_USE_FENCE_SYNC"
-#endif
- "]";
- configStr.append(config);
-}
-
-}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 65a1a01..4c7d365 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1921,57 +1921,29 @@
}
// ----------------------------------------------------------------------------
-status_t SyncScreenCaptureListener::onScreenCaptureComplete(
- const ScreenCaptureResults& captureResults) {
- resultsPromise.set_value(captureResults);
- return NO_ERROR;
-}
-
-ScreenCaptureResults SyncScreenCaptureListener::waitForResults() {
- std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
- return resultsFuture.get();
-}
status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
- sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- status_t status = s->captureDisplay(captureArgs, captureListener);
- if (status != NO_ERROR) {
- return status;
- }
- captureResults = captureListener->waitForResults();
- return captureResults.result;
+ return s->captureDisplay(captureArgs, captureListener);
}
status_t ScreenshotClient::captureDisplay(uint64_t displayOrLayerStack,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
- sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- status_t status = s->captureDisplay(displayOrLayerStack, captureListener);
- if (status != NO_ERROR) {
- return status;
- }
- captureResults = captureListener->waitForResults();
- return captureResults.result;
+ return s->captureDisplay(displayOrLayerStack, captureListener);
}
status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
- sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- status_t status = s->captureLayers(captureArgs, captureListener);
- if (status != NO_ERROR) {
- return status;
- }
- captureResults = captureListener->waitForResults();
- return captureResults.result;
+ return s->captureLayers(captureArgs, captureListener);
}
} // namespace android
diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp
index 8df6e81..1a8fc1a 100644
--- a/libs/gui/SyncFeatures.cpp
+++ b/libs/gui/SyncFeatures.cpp
@@ -71,15 +71,7 @@
return mHasNativeFenceSync;
}
bool SyncFeatures::useFenceSync() const {
-#ifdef DONT_USE_FENCE_SYNC
- // on some devices it's better to not use EGL_KHR_fence_sync
- // even if they have it
- return false;
-#else
- // currently we shall only attempt to use EGL_KHR_fence_sync if
- // USE_FENCE_SYNC is set in our makefile
return !mHasNativeFenceSync && mHasFenceSync;
-#endif
}
bool SyncFeatures::useWaitSync() const {
return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync;
diff --git a/libs/gui/include/gui/GuiConfig.h b/libs/gui/include/gui/GuiConfig.h
deleted file mode 100644
index 7aa5432..0000000
--- a/libs/gui/include/gui/GuiConfig.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GUI_CONFIG_H
-#define ANDROID_GUI_CONFIG_H
-
-#include <string>
-
-namespace android {
-
-// Append the libgui configuration details to configStr.
-void appendGuiConfigString(std::string& configStr);
-
-}; // namespace android
-
-#endif /*ANDROID_GUI_CONFIG_H*/
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 05151ba..dc1d936 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -18,7 +18,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <future>
#include <set>
#include <unordered_map>
#include <unordered_set>
@@ -594,23 +593,14 @@
// ---------------------------------------------------------------------------
-class SyncScreenCaptureListener : public BnScreenCaptureListener {
-public:
- status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override;
- ScreenCaptureResults waitForResults();
-
-private:
- std::promise<ScreenCaptureResults> resultsPromise;
-};
-
class ScreenshotClient {
public:
static status_t captureDisplay(const DisplayCaptureArgs& captureArgs,
- ScreenCaptureResults& captureResults);
+ const sp<IScreenCaptureListener>& captureListener);
static status_t captureDisplay(uint64_t displayOrLayerStack,
- ScreenCaptureResults& captureResults);
+ const sp<IScreenCaptureListener>& captureListener);
static status_t captureLayers(const LayerCaptureArgs& captureArgs,
- ScreenCaptureResults& captureResults);
+ const sp<IScreenCaptureListener>& captureListener);
};
// ---------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/SyncScreenCaptureListener.h b/libs/gui/include/gui/SyncScreenCaptureListener.h
new file mode 100644
index 0000000..2857996
--- /dev/null
+++ b/libs/gui/include/gui/SyncScreenCaptureListener.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gui/SurfaceComposerClient.h>
+#include <future>
+
+namespace android {
+
+class SyncScreenCaptureListener : public BnScreenCaptureListener {
+public:
+ status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override {
+ resultsPromise.set_value(captureResults);
+ return NO_ERROR;
+ }
+
+ ScreenCaptureResults waitForResults() {
+ std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
+ return resultsFuture.get();
+ }
+
+private:
+ std::promise<ScreenCaptureResults> resultsPromise;
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 4a186b1..da0d5f8 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -25,6 +25,7 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
#include <gui/SurfaceComposerClient.h>
+#include <gui/SyncScreenCaptureListener.h>
#include <private/gui/ComposerService.h>
#include <ui/DisplayConfig.h>
#include <ui/GraphicBuffer.h>
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index aedba2a..dbede46 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -28,6 +28,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
+#include <gui/SyncScreenCaptureListener.h>
#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <ui/BufferQueueDefs.h>
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 392d478..8f575a8 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -36,6 +36,7 @@
"Keyboard.cpp",
"KeyCharacterMap.cpp",
"KeyLayoutMap.cpp",
+ "PropertyMap.cpp",
"TouchVideoFrame.cpp",
"VirtualKeyMap.cpp",
],
@@ -97,4 +98,23 @@
},
}
+cc_defaults {
+ name: "libinput_fuzz_defaults",
+ host_supported: true,
+ shared_libs: [
+ "libutils",
+ "libbase",
+ "liblog",
+ ],
+}
+
+cc_fuzz {
+ name: "libinput_fuzz_propertymap",
+ defaults: ["libinput_fuzz_defaults"],
+ srcs: [
+ "PropertyMap.cpp",
+ "PropertyMap_fuzz.cpp",
+ ],
+}
+
subdirs = ["tests"]
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 51910fe..692c65d 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "Input"
//#define LOG_NDEBUG 0
+#include <attestation/HmacKeyManager.h>
#include <cutils/compiler.h>
#include <limits.h>
#include <string.h>
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index fd35131..7ac8a2e 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -24,9 +24,10 @@
#endif
#include <android/keycodes.h>
+#include <attestation/HmacKeyManager.h>
#include <input/InputEventLabels.h>
-#include <input/Keyboard.h>
#include <input/KeyCharacterMap.h>
+#include <input/Keyboard.h>
#include <utils/Log.h>
#include <utils/Errors.h>
diff --git a/libs/input/PropertyMap.cpp b/libs/input/PropertyMap.cpp
new file mode 100644
index 0000000..4833eb9
--- /dev/null
+++ b/libs/input/PropertyMap.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PropertyMap"
+
+#include <input/PropertyMap.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r=";
+
+// --- PropertyMap ---
+
+PropertyMap::PropertyMap() {}
+
+PropertyMap::~PropertyMap() {}
+
+void PropertyMap::clear() {
+ mProperties.clear();
+}
+
+void PropertyMap::addProperty(const String8& key, const String8& value) {
+ mProperties.add(key, value);
+}
+
+bool PropertyMap::hasProperty(const String8& key) const {
+ return mProperties.indexOfKey(key) >= 0;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {
+ ssize_t index = mProperties.indexOfKey(key);
+ if (index < 0) {
+ return false;
+ }
+
+ outValue = mProperties.valueAt(index);
+ return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
+ int32_t intValue;
+ if (!tryGetProperty(key, intValue)) {
+ return false;
+ }
+
+ outValue = intValue;
+ return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {
+ String8 stringValue;
+ if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+ return false;
+ }
+
+ char* end;
+ int value = strtol(stringValue.string(), &end, 10);
+ if (*end != '\0') {
+ ALOGW("Property key '%s' has invalid value '%s'. Expected an integer.", key.string(),
+ stringValue.string());
+ return false;
+ }
+ outValue = value;
+ return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
+ String8 stringValue;
+ if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+ return false;
+ }
+
+ char* end;
+ float value = strtof(stringValue.string(), &end);
+ if (*end != '\0') {
+ ALOGW("Property key '%s' has invalid value '%s'. Expected a float.", key.string(),
+ stringValue.string());
+ return false;
+ }
+ outValue = value;
+ return true;
+}
+
+void PropertyMap::addAll(const PropertyMap* map) {
+ for (size_t i = 0; i < map->mProperties.size(); i++) {
+ mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));
+ }
+}
+
+status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) {
+ *outMap = nullptr;
+
+ Tokenizer* tokenizer;
+ status_t status = Tokenizer::open(filename, &tokenizer);
+ if (status) {
+ ALOGE("Error %d opening property file %s.", status, filename.string());
+ } else {
+ PropertyMap* map = new PropertyMap();
+ if (!map) {
+ ALOGE("Error allocating property map.");
+ status = NO_MEMORY;
+ } else {
+#if DEBUG_PARSER_PERFORMANCE
+ nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ Parser parser(map, tokenizer);
+ status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+ nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+ ALOGD("Parsed property file '%s' %d lines in %0.3fms.",
+ tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+ elapsedTime / 1000000.0);
+#endif
+ if (status) {
+ delete map;
+ } else {
+ *outMap = map;
+ }
+ }
+ delete tokenizer;
+ }
+ return status;
+}
+
+// --- PropertyMap::Parser ---
+
+PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer)
+ : mMap(map), mTokenizer(tokenizer) {}
+
+PropertyMap::Parser::~Parser() {}
+
+status_t PropertyMap::Parser::parse() {
+ while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+ ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+ mTokenizer->peekRemainderOfLine().string());
+#endif
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+
+ if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+ String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+ if (keyToken.isEmpty()) {
+ ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+
+ if (mTokenizer->nextChar() != '=') {
+ ALOGE("%s: Expected '=' between property key and value.",
+ mTokenizer->getLocation().string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+
+ String8 valueToken = mTokenizer->nextToken(WHITESPACE);
+ if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) {
+ ALOGE("%s: Found reserved character '\\' or '\"' in property value.",
+ mTokenizer->getLocation().string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ if (!mTokenizer->isEol()) {
+ ALOGE("%s: Expected end of line, got '%s'.", mTokenizer->getLocation().string(),
+ mTokenizer->peekRemainderOfLine().string());
+ return BAD_VALUE;
+ }
+
+ if (mMap->hasProperty(keyToken)) {
+ ALOGE("%s: Duplicate property value for key '%s'.",
+ mTokenizer->getLocation().string(), keyToken.string());
+ return BAD_VALUE;
+ }
+
+ mMap->addProperty(keyToken, valueToken);
+ }
+
+ mTokenizer->nextLine();
+ }
+ return OK;
+}
+
+} // namespace android
diff --git a/libs/input/PropertyMap_fuzz.cpp b/libs/input/PropertyMap_fuzz.cpp
new file mode 100755
index 0000000..23ead0e
--- /dev/null
+++ b/libs/input/PropertyMap_fuzz.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/file.h"
+#include "fuzzer/FuzzedDataProvider.h"
+#include "input/PropertyMap.h"
+#include "utils/String8.h"
+
+static constexpr int MAX_FILE_SIZE = 256;
+static constexpr int MAX_STR_LEN = 2048;
+static constexpr int MAX_OPERATIONS = 1000;
+
+static const std::vector<std::function<void(FuzzedDataProvider*, android::PropertyMap)>>
+ operations = {
+ [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
+ propertyMap.getProperties();
+ },
+ [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
+ propertyMap.clear();
+ },
+ [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+ std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+ android::String8 key = android::String8(keyStr.c_str());
+ propertyMap.hasProperty(key);
+ },
+ [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+ std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+ android::String8 key = android::String8(keyStr.c_str());
+ android::String8 out;
+ propertyMap.tryGetProperty(key, out);
+ },
+ [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+ TemporaryFile tf;
+ // Generate file contents
+ std::string contents = dataProvider->ConsumeRandomLengthString(MAX_FILE_SIZE);
+ // If we have string contents, dump them into the file.
+ // Otherwise, just leave it as an empty file.
+ if (contents.length() > 0) {
+ const char* bytes = contents.c_str();
+ android::base::WriteStringToFd(bytes, tf.fd);
+ }
+ android::PropertyMap* mapPtr = &propertyMap;
+ android::PropertyMap::load(android::String8(tf.path), &mapPtr);
+ },
+ [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+ std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+ std::string valStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+ android::String8 key = android::String8(keyStr.c_str());
+ android::String8 val = android::String8(valStr.c_str());
+ propertyMap.addProperty(key, val);
+ },
+};
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider dataProvider(data, size);
+ android::PropertyMap proprtyMap = android::PropertyMap();
+
+ int opsRun = 0;
+ while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
+ uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+ operations[op](&dataProvider, proprtyMap);
+ }
+ return 0;
+}
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 069bc0e..601d8da 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -17,6 +17,7 @@
#include <array>
#include <math.h>
+#include <attestation/HmacKeyManager.h>
#include <binder/Parcel.h>
#include <gtest/gtest.h>
#include <input/Input.h>
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index e1f2562..1452745 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -20,11 +20,12 @@
#include <sys/mman.h>
#include <time.h>
+#include <attestation/HmacKeyManager.h>
#include <cutils/ashmem.h>
#include <gtest/gtest.h>
#include <input/InputTransport.h>
-#include <utils/Timers.h>
#include <utils/StopWatch.h>
+#include <utils/Timers.h>
namespace android {
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index e7db4b0..d049d05 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -21,6 +21,7 @@
#include <math.h>
#include <android-base/stringprintf.h>
+#include <attestation/HmacKeyManager.h>
#include <gtest/gtest.h>
#include <input/VelocityTracker.h>
diff --git a/libs/input/tests/VerifiedInputEvent_test.cpp b/libs/input/tests/VerifiedInputEvent_test.cpp
index 21cfe8c..36f87b8 100644
--- a/libs/input/tests/VerifiedInputEvent_test.cpp
+++ b/libs/input/tests/VerifiedInputEvent_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <attestation/HmacKeyManager.h>
#include <gtest/gtest.h>
#include <input/Input.h>
diff --git a/libs/renderengine/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp
index c3fbb60..eb0074b 100644
--- a/libs/renderengine/RenderEngine.cpp
+++ b/libs/renderengine/RenderEngine.cpp
@@ -62,10 +62,6 @@
return SyncFeatures::getInstance().useNativeFenceSync();
}
-bool RenderEngine::useWaitSync() const {
- return SyncFeatures::getInstance().useWaitSync();
-}
-
} // namespace impl
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 3dcfebe..3090d19 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -114,6 +114,28 @@
namespace renderengine {
namespace gl {
+class BindNativeBufferAsFramebuffer {
+public:
+ BindNativeBufferAsFramebuffer(GLESRenderEngine& engine, ANativeWindowBuffer* buffer,
+ const bool useFramebufferCache)
+ : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
+ mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(),
+ useFramebufferCache)
+ ? mEngine.bindFrameBuffer(mFramebuffer)
+ : NO_MEMORY;
+ }
+ ~BindNativeBufferAsFramebuffer() {
+ mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true);
+ mEngine.unbindFrameBuffer(mFramebuffer);
+ }
+ status_t getStatus() const { return mStatus; }
+
+private:
+ GLESRenderEngine& mEngine;
+ Framebuffer* mFramebuffer;
+ status_t mStatus;
+};
+
using base::StringAppendF;
using ui::Dataspace;
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 2c6eae2..2a98bd8 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -60,13 +60,10 @@
void primeCache() const override;
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
- void bindExternalTextureImage(uint32_t texName, const Image& image) override;
status_t bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
const sp<Fence>& fence) EXCLUDES(mRenderingMutex);
void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);
- status_t bindFrameBuffer(Framebuffer* framebuffer) override;
- void unbindFrameBuffer(Framebuffer* framebuffer) override;
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
@@ -102,13 +99,15 @@
std::shared_ptr<ImageManager::Barrier> unbindExternalTextureBufferForTesting(uint64_t bufferId);
protected:
- Framebuffer* getFramebufferForDrawing() override;
+ Framebuffer* getFramebufferForDrawing();
void dump(std::string& result) override EXCLUDES(mRenderingMutex)
EXCLUDES(mFramebufferImageCacheMutex);
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
private:
+ friend class BindNativeBufferAsFramebuffer;
+
enum GlesVersion {
GLES_VERSION_1_0 = 0x10000,
GLES_VERSION_1_1 = 0x10001,
@@ -133,6 +132,9 @@
status_t cacheExternalTextureBufferInternal(const sp<GraphicBuffer>& buffer)
EXCLUDES(mRenderingMutex);
void unbindExternalTextureBufferInternal(uint64_t bufferId) EXCLUDES(mRenderingMutex);
+ status_t bindFrameBuffer(Framebuffer* framebuffer);
+ void unbindFrameBuffer(Framebuffer* framebuffer);
+ void bindExternalTextureImage(uint32_t texName, const Image& image);
// A data space is considered HDR data space if it has BT2020 color space
// with PQ or HLG transfer function.
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 09a0f65..6db2af8 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -44,7 +44,6 @@
namespace renderengine {
-class BindNativeBufferAsFramebuffer;
class Image;
class Mesh;
class Texture;
@@ -90,10 +89,8 @@
virtual void dump(std::string& result) = 0;
virtual bool useNativeFenceSync() const = 0;
- virtual bool useWaitSync() const = 0;
virtual void genTextures(size_t count, uint32_t* names) = 0;
virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
- virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
// Legacy public method used by devices that don't support native fence
// synchronization in their GPU driver, as this method provides implicit
// synchronization for latching buffers.
@@ -116,10 +113,6 @@
// a buffer should never occur before binding the buffer if the caller
// called {bind, cache}ExternalTextureBuffer before calling unbind.
virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
- // When binding a native buffer, it must be done before setViewportAndProjection
- // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
- virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
- virtual void unbindFrameBuffer(Framebuffer* framebuffer) = 0;
enum class CleanupMode {
CLEAN_OUTPUT_RESOURCES,
@@ -187,13 +180,6 @@
base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
protected:
- // Gets a framebuffer to render to. This framebuffer may or may not be
- // cached depending on the implementation.
- //
- // Note that this method does not transfer ownership, so the caller most not
- // live longer than RenderEngine.
- virtual Framebuffer* getFramebufferForDrawing() = 0;
- friend class BindNativeBufferAsFramebuffer;
friend class threaded::RenderEngineThreaded;
};
@@ -280,28 +266,6 @@
RenderEngine::RenderEngineType renderEngineType = RenderEngine::RenderEngineType::GLES;
};
-class BindNativeBufferAsFramebuffer {
-public:
- BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer,
- const bool useFramebufferCache)
- : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
- mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(),
- useFramebufferCache)
- ? mEngine.bindFrameBuffer(mFramebuffer)
- : NO_MEMORY;
- }
- ~BindNativeBufferAsFramebuffer() {
- mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true);
- mEngine.unbindFrameBuffer(mFramebuffer);
- }
- status_t getStatus() const { return mStatus; }
-
-private:
- RenderEngine& mEngine;
- Framebuffer* mFramebuffer;
- status_t mStatus;
-};
-
namespace impl {
// impl::RenderEngine contains common implementation that is graphics back-end agnostic.
@@ -310,7 +274,6 @@
virtual ~RenderEngine() = 0;
bool useNativeFenceSync() const override;
- bool useWaitSync() const override;
protected:
RenderEngine(const RenderEngineCreationArgs& args);
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index e03dd58..3fd125e 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -43,7 +43,6 @@
MOCK_CONST_METHOD0(isCurrent, bool());
MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
- MOCK_METHOD2(bindExternalTextureImage, void(uint32_t, const renderengine::Image&));
MOCK_METHOD1(cacheExternalTextureBuffer, void(const sp<GraphicBuffer>&));
MOCK_METHOD3(bindExternalTextureBuffer,
status_t(uint32_t, const sp<GraphicBuffer>&, const sp<Fence>&));
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index 97c7442..78fec29 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -93,26 +93,6 @@
mThreadedRE->unbindExternalTextureBuffer(0x0);
}
-TEST_F(RenderEngineThreadedTest, bindFrameBuffer_returnsBadValue) {
- std::unique_ptr<renderengine::Framebuffer> framebuffer;
- EXPECT_CALL(*mRenderEngine, bindFrameBuffer(framebuffer.get())).WillOnce(Return(BAD_VALUE));
- status_t result = mThreadedRE->bindFrameBuffer(framebuffer.get());
- ASSERT_EQ(BAD_VALUE, result);
-}
-
-TEST_F(RenderEngineThreadedTest, bindFrameBuffer_returnsNoError) {
- std::unique_ptr<renderengine::Framebuffer> framebuffer;
- EXPECT_CALL(*mRenderEngine, bindFrameBuffer(framebuffer.get())).WillOnce(Return(NO_ERROR));
- status_t result = mThreadedRE->bindFrameBuffer(framebuffer.get());
- ASSERT_EQ(NO_ERROR, result);
-}
-
-TEST_F(RenderEngineThreadedTest, unbindFrameBuffer) {
- std::unique_ptr<renderengine::Framebuffer> framebuffer;
- EXPECT_CALL(*mRenderEngine, unbindFrameBuffer(framebuffer.get()));
- mThreadedRE->unbindFrameBuffer(framebuffer.get());
-}
-
TEST_F(RenderEngineThreadedTest, getMaxTextureSize_returns20) {
size_t size = 20;
EXPECT_CALL(*mRenderEngine, getMaxTextureSize()).WillOnce(Return(size));
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index d4184fd..dc47070 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -131,21 +131,6 @@
return resultFuture.get();
}
-bool RenderEngineThreaded::useWaitSync() const {
- std::promise<bool> resultPromise;
- std::future<bool> resultFuture = resultPromise.get_future();
- {
- std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& /*instance*/) {
- ATRACE_NAME("REThreaded::useWaitSync");
- bool returnValue = SyncFeatures::getInstance().useWaitSync();
- resultPromise.set_value(returnValue);
- });
- }
- mCondition.notify_one();
- return resultFuture.get();
-}
-
void RenderEngineThreaded::genTextures(size_t count, uint32_t* names) {
std::promise<void> resultPromise;
std::future<void> resultFuture = resultPromise.get_future();
@@ -176,22 +161,6 @@
resultFuture.wait();
}
-void RenderEngineThreaded::bindExternalTextureImage(uint32_t texName, const Image& image) {
- std::promise<void> resultPromise;
- std::future<void> resultFuture = resultPromise.get_future();
- {
- std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push(
- [&resultPromise, texName, &image](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::bindExternalTextureImage");
- instance.bindExternalTextureImage(texName, image);
- resultPromise.set_value();
- });
- }
- mCondition.notify_one();
- resultFuture.wait();
-}
-
status_t RenderEngineThreaded::bindExternalTextureBuffer(uint32_t texName,
const sp<GraphicBuffer>& buffer,
const sp<Fence>& fence) {
@@ -240,36 +209,6 @@
resultFuture.wait();
}
-status_t RenderEngineThreaded::bindFrameBuffer(Framebuffer* framebuffer) {
- std::promise<status_t> resultPromise;
- std::future<status_t> resultFuture = resultPromise.get_future();
- {
- std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push([&resultPromise, &framebuffer](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::bindFrameBuffer");
- status_t status = instance.bindFrameBuffer(framebuffer);
- resultPromise.set_value(status);
- });
- }
- mCondition.notify_one();
- return resultFuture.get();
-}
-
-void RenderEngineThreaded::unbindFrameBuffer(Framebuffer* framebuffer) {
- std::promise<void> resultPromise;
- std::future<void> resultFuture = resultPromise.get_future();
- {
- std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push([&resultPromise, &framebuffer](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::unbindFrameBuffer");
- instance.unbindFrameBuffer(framebuffer);
- resultPromise.set_value();
- });
- }
- mCondition.notify_one();
- resultFuture.wait();
-}
-
size_t RenderEngineThreaded::getMaxTextureSize() const {
std::promise<size_t> resultPromise;
std::future<size_t> resultFuture = resultPromise.get_future();
@@ -346,21 +285,6 @@
return resultFuture.get();
}
-Framebuffer* RenderEngineThreaded::getFramebufferForDrawing() {
- std::promise<Framebuffer*> resultPromise;
- std::future<Framebuffer*> resultFuture = resultPromise.get_future();
- {
- std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::getFramebufferForDrawing");
- Framebuffer* framebuffer = instance.getFramebufferForDrawing();
- resultPromise.set_value(framebuffer);
- });
- }
- mCondition.notify_one();
- return resultFuture.get();
-}
-
bool RenderEngineThreaded::cleanupPostRender(CleanupMode mode) {
std::promise<bool> resultPromise;
std::future<bool> resultFuture = resultPromise.get_future();
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index 86a49e9..96a49b3 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -46,16 +46,12 @@
void dump(std::string& result) override;
bool useNativeFenceSync() const override;
- bool useWaitSync() const override;
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
- void bindExternalTextureImage(uint32_t texName, const Image& image) override;
status_t bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
const sp<Fence>& fence) override;
void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
void unbindExternalTextureBuffer(uint64_t bufferId) override;
- status_t bindFrameBuffer(Framebuffer* framebuffer) override;
- void unbindFrameBuffer(Framebuffer* framebuffer) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
@@ -69,9 +65,6 @@
const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
-protected:
- Framebuffer* getFramebufferForDrawing() override;
-
private:
void threadMain(CreateInstanceFactory factory);
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 2acc5bb..3fa2e53 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -120,7 +120,6 @@
"PixelFormat.cpp",
"PublicFormat.cpp",
"Size.cpp",
- "UiConfig.cpp",
],
include_dirs: [
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 943d13e..91d2d58 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -83,20 +83,17 @@
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
uint64_t total = 0;
result.append("GraphicBufferAllocator buffers:\n");
- const size_t c = list.size();
- for (size_t i=0 ; i<c ; i++) {
+ const size_t count = list.size();
+ StringAppendF(&result, "%10s | %11s | %18s | %s | %8s | %10s | %s\n", "Handle", "Size",
+ "W (Stride) x H", "Layers", "Format", "Usage", "Requestor");
+ for (size_t i = 0; i < count; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- if (rec.size) {
- StringAppendF(&result,
- "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n",
- list.keyAt(i), static_cast<double>(rec.size) / 1024.0, rec.width, rec.stride, rec.height,
- rec.layerCount, rec.format, rec.usage, rec.requestorName.c_str());
- } else {
- StringAppendF(&result,
- "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n",
- list.keyAt(i), rec.width, rec.stride, rec.height, rec.layerCount,
- rec.format, rec.usage, rec.requestorName.c_str());
- }
+ std::string sizeStr = (rec.size)
+ ? base::StringPrintf("%7.2f KiB", static_cast<double>(rec.size) / 1024.0)
+ : "unknown";
+ StringAppendF(&result, "%10p | %11s | %4u (%4u) x %4u | %6u | %8X | 0x%8" PRIx64 " | %s\n",
+ list.keyAt(i), sizeStr.c_str(), rec.width, rec.stride, rec.height,
+ rec.layerCount, rec.format, rec.usage, rec.requestorName.c_str());
total += rec.size;
}
StringAppendF(&result, "Total allocated by GraphicBufferAllocator (estimate): %.2f KB\n",
diff --git a/libs/ui/UiConfig.cpp b/libs/ui/UiConfig.cpp
deleted file mode 100644
index 0ac863d..0000000
--- a/libs/ui/UiConfig.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ui/UiConfig.h>
-
-namespace android {
-
-void appendUiConfigString(std::string& configStr) {
- static const char* config =
- " [libui]";
- configStr.append(config);
-}
-
-
-}; // namespace android
diff --git a/libs/ui/include/ui/UiConfig.h b/libs/ui/include/ui/UiConfig.h
deleted file mode 100644
index d1d6014..0000000
--- a/libs/ui/include/ui/UiConfig.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_UI_CONFIG_H
-#define ANDROID_UI_CONFIG_H
-
-#include <string>
-
-namespace android {
-
-// Append the libui configuration details to configStr.
-void appendUiConfigString(std::string& configStr);
-
-}; // namespace android
-
-#endif /*ANDROID_UI_CONFIG_H*/
diff --git a/libs/ui/include_vndk/ui/UiConfig.h b/libs/ui/include_vndk/ui/UiConfig.h
deleted file mode 120000
index f580ce1..0000000
--- a/libs/ui/include_vndk/ui/UiConfig.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/ui/UiConfig.h
\ No newline at end of file
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index a0de607..96e6207 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -59,6 +59,9 @@
"libutils",
"libui",
],
+ static_libs: [
+ "libattestation",
+ ],
}
cc_library_shared {
diff --git a/services/inputflinger/benchmarks/Android.bp b/services/inputflinger/benchmarks/Android.bp
index 066a816..9abf8b1 100644
--- a/services/inputflinger/benchmarks/Android.bp
+++ b/services/inputflinger/benchmarks/Android.bp
@@ -18,6 +18,7 @@
"libutils",
],
static_libs: [
+ "libattestation",
"libinputdispatcher",
],
}
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index d29d8df..ff9aac9 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -48,6 +48,9 @@
"libui",
"libutils",
],
+ static_libs: [
+ "libattestation",
+ ],
header_libs: [
"libinputdispatcher_headers",
],
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9c8481c..b428c4e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -53,8 +53,6 @@
#include <input/InputWindow.h>
#include <log/log.h>
#include <log/log_event_list.h>
-#include <openssl/hmac.h>
-#include <openssl/rand.h>
#include <powermanager/PowerManager.h>
#include <statslog.h>
#include <unistd.h>
@@ -344,53 +342,6 @@
}
}
-static std::array<uint8_t, 128> getRandomKey() {
- std::array<uint8_t, 128> key;
- if (RAND_bytes(key.data(), key.size()) != 1) {
- LOG_ALWAYS_FATAL("Can't generate HMAC key");
- }
- return key;
-}
-
-// --- HmacKeyManager ---
-
-HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {}
-
-std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const {
- size_t size;
- switch (event.type) {
- case VerifiedInputEvent::Type::KEY: {
- size = sizeof(VerifiedKeyEvent);
- break;
- }
- case VerifiedInputEvent::Type::MOTION: {
- size = sizeof(VerifiedMotionEvent);
- break;
- }
- }
- const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
- return sign(start, size);
-}
-
-std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const {
- // SHA256 always generates 32-bytes result
- std::array<uint8_t, 32> hash;
- unsigned int hashLen = 0;
- uint8_t* result =
- HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen);
- if (result == nullptr) {
- ALOGE("Could not sign the data using HMAC");
- return INVALID_HMAC;
- }
-
- if (hashLen != hash.size()) {
- ALOGE("HMAC-SHA256 has unexpected length");
- return INVALID_HMAC;
- }
-
- return hash;
-}
-
// --- InputDispatcher ---
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
@@ -2682,6 +2633,22 @@
}
}
+std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
+ size_t size;
+ switch (event.type) {
+ case VerifiedInputEvent::Type::KEY: {
+ size = sizeof(VerifiedKeyEvent);
+ break;
+ }
+ case VerifiedInputEvent::Type::MOTION: {
+ size = sizeof(VerifiedMotionEvent);
+ break;
+ }
+ }
+ const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
+ return mHmacKeyManager.sign(start, size);
+}
+
const std::array<uint8_t, 32> InputDispatcher::getSignature(
const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
@@ -2691,7 +2658,7 @@
VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
verifiedEvent.actionMasked = actionMasked;
verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
- return mHmacKeyManager.sign(verifiedEvent);
+ return sign(verifiedEvent);
}
return INVALID_HMAC;
}
@@ -2701,7 +2668,7 @@
VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
verifiedEvent.action = dispatchEntry.resolvedAction;
- return mHmacKeyManager.sign(verifiedEvent);
+ return sign(verifiedEvent);
}
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
@@ -3549,7 +3516,7 @@
const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
- calculatedHmac = mHmacKeyManager.sign(verifiedKeyEvent);
+ calculatedHmac = sign(verifiedKeyEvent);
break;
}
case AINPUT_EVENT_TYPE_MOTION: {
@@ -3557,7 +3524,7 @@
VerifiedMotionEvent verifiedMotionEvent =
verifiedMotionEventFromMotionEvent(motionEvent);
result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
- calculatedHmac = mHmacKeyManager.sign(verifiedMotionEvent);
+ calculatedHmac = sign(verifiedMotionEvent);
break;
}
default: {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index c52d256..93d3fde 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -31,6 +31,7 @@
#include "TouchState.h"
#include "TouchedWindow.h"
+#include <attestation/HmacKeyManager.h>
#include <input/Input.h>
#include <input/InputApplication.h>
#include <input/InputTransport.h>
@@ -58,16 +59,6 @@
class Connection;
-class HmacKeyManager {
-public:
- HmacKeyManager();
- std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
-
-private:
- std::array<uint8_t, 32> sign(const uint8_t* data, size_t size) const;
- const std::array<uint8_t, 128> mHmacKey;
-};
-
/* Dispatches events to input targets. Some functions of the input dispatcher, such as
* identifying input targets, are controlled by a separate policy object.
*
@@ -133,6 +124,8 @@
virtual status_t unregisterInputChannel(const InputChannel& inputChannel) override;
virtual status_t pilferPointers(const sp<IBinder>& token) override;
+ std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
+
private:
enum class DropReason {
NOT_DROPPED,
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
index ff69800..cabc782 100644
--- a/services/inputflinger/host/InputDriver.cpp
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -29,8 +29,8 @@
#include <hardware/input.h>
#include <input/InputDevice.h>
+#include <input/PropertyMap.h>
#include <utils/Log.h>
-#include <utils/PropertyMap.h>
#include <utils/String8.h>
#define INDENT2 " "
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index aec4837..edb82d3 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -28,6 +28,7 @@
#include <input/KeyCharacterMap.h>
#include <input/KeyLayoutMap.h>
#include <input/Keyboard.h>
+#include <input/PropertyMap.h>
#include <input/VirtualKeyMap.h>
#include <linux/input.h>
#include <sys/epoll.h>
@@ -37,7 +38,6 @@
#include <utils/List.h>
#include <utils/Log.h>
#include <utils/Mutex.h>
-#include <utils/PropertyMap.h>
#include "TouchVideoDevice.h"
#include "VibrationElement.h"
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 7f5e1c8..6b28069 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -20,8 +20,8 @@
#include <input/DisplayViewport.h>
#include <input/Flags.h>
#include <input/InputDevice.h>
+#include <input/PropertyMap.h>
#include <stdint.h>
-#include <utils/PropertyMap.h>
#include <optional>
#include <unordered_map>
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 65f9781..8b9f235 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -419,6 +419,25 @@
void KeyboardInputMapper::updateLedState(bool reset) {
mMetaState |= getContext()->getLedMetaState();
+
+ constexpr int32_t META_NUM = 3;
+ const std::array<int32_t, META_NUM> keyCodes = {AKEYCODE_CAPS_LOCK, AKEYCODE_NUM_LOCK,
+ AKEYCODE_SCROLL_LOCK};
+ const std::array<int32_t, META_NUM> metaCodes = {AMETA_CAPS_LOCK_ON, AMETA_NUM_LOCK_ON,
+ AMETA_SCROLL_LOCK_ON};
+ std::array<uint8_t, META_NUM> flags = {0, 0, 0};
+ bool hasKeyLayout =
+ getDeviceContext().markSupportedKeyCodes(META_NUM, keyCodes.data(), flags.data());
+ // If the device doesn't have the physical meta key it shouldn't generate the corresponding
+ // meta state.
+ if (hasKeyLayout) {
+ for (int i = 0; i < META_NUM; i++) {
+ if (!flags[i]) {
+ mMetaState &= ~metaCodes[i];
+ }
+ }
+ }
+
updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK, AMETA_CAPS_LOCK_ON, reset);
updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK, AMETA_NUM_LOCK_ON, reset);
updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, reset);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index da50af5..3e0b5e8 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -294,70 +294,6 @@
}
};
-// --- HmacKeyManagerTest ---
-
-class HmacKeyManagerTest : public testing::Test {
-protected:
- HmacKeyManager mHmacKeyManager;
-};
-
-/**
- * Ensure that separate calls to sign the same data are generating the same key.
- * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
- * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
- * tests.
- */
-TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) {
- KeyEvent event = getTestKeyEvent();
- VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
-
- std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(verifiedEvent);
- std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(verifiedEvent);
- ASSERT_EQ(hmac1, hmac2);
-}
-
-/**
- * Ensure that changes in VerifiedKeyEvent produce a different hmac.
- */
-TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) {
- KeyEvent event = getTestKeyEvent();
- VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
- std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(verifiedEvent);
-
- verifiedEvent.deviceId += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.source += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.eventTimeNanos += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.displayId += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.action += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.downTimeNanos += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.flags += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.keyCode += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.scanCode += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.metaState += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-
- verifiedEvent.repeatCount += 1;
- ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
-}
-
// --- InputDispatcherTest ---
class InputDispatcherTest : public testing::Test {
@@ -2027,6 +1963,63 @@
EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
}
+/**
+ * Ensure that separate calls to sign the same data are generating the same key.
+ * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
+ * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
+ * tests.
+ */
+TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
+ KeyEvent event = getTestKeyEvent();
+ VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
+
+ std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
+ std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
+ ASSERT_EQ(hmac1, hmac2);
+}
+
+/**
+ * Ensure that changes in VerifiedKeyEvent produce a different hmac.
+ */
+TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
+ KeyEvent event = getTestKeyEvent();
+ VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
+ std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
+
+ verifiedEvent.deviceId += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.source += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.eventTimeNanos += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.displayId += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.action += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.downTimeNanos += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.flags += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.keyCode += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.scanCode += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.metaState += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+
+ verifiedEvent.repeatCount += 1;
+ ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
+}
+
class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
protected:
static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index b28b6ea..f56735a 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -102,29 +102,23 @@
mMaxY = maxY;
}
- virtual void setPosition(float x, float y) {
+ void setPosition(float x, float y) override {
mX = x;
mY = y;
}
- virtual void setButtonState(int32_t buttonState) {
- mButtonState = buttonState;
- }
+ void setButtonState(int32_t buttonState) override { mButtonState = buttonState; }
- virtual int32_t getButtonState() const {
- return mButtonState;
- }
+ int32_t getButtonState() const override { return mButtonState; }
- virtual void getPosition(float* outX, float* outY) const {
+ void getPosition(float* outX, float* outY) const override {
*outX = mX;
*outY = mY;
}
- virtual int32_t getDisplayId() const {
- return mDisplayId;
- }
+ int32_t getDisplayId() const override { return mDisplayId; }
- virtual void setDisplayViewport(const DisplayViewport& viewport) {
+ void setDisplayViewport(const DisplayViewport& viewport) override {
mDisplayId = viewport.displayId;
}
@@ -133,7 +127,7 @@
}
private:
- virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
+ bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
*outMinX = mMinX;
*outMinY = mMinY;
*outMaxX = mMaxX;
@@ -141,7 +135,7 @@
return mHaveBounds;
}
- virtual void move(float deltaX, float deltaY) {
+ void move(float deltaX, float deltaY) override {
mX += deltaX;
if (mX < mMinX) mX = mMinX;
if (mX > mMaxX) mX = mMaxX;
@@ -150,17 +144,14 @@
if (mY > mMaxY) mY = mMaxY;
}
- virtual void fade(Transition) {
- }
+ void fade(Transition) override {}
- virtual void unfade(Transition) {
- }
+ void unfade(Transition) override {}
- virtual void setPresentation(Presentation) {
- }
+ void setPresentation(Presentation) override {}
- virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
- int32_t displayId) {
+ void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
+ int32_t displayId) override {
std::vector<int32_t> newSpots;
// Add spots for fingers that are down.
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
@@ -171,8 +162,7 @@
mSpotsByDisplay[displayId] = newSpots;
}
- virtual void clearSpots() {
- }
+ void clearSpots() override {}
std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
};
@@ -192,7 +182,7 @@
TouchAffineTransformation transform;
protected:
- virtual ~FakeInputReaderPolicy() { }
+ virtual ~FakeInputReaderPolicy() {}
public:
FakeInputReaderPolicy() {
@@ -325,29 +315,27 @@
return v;
}
- virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
+ void getReaderConfiguration(InputReaderConfiguration* outConfig) override {
*outConfig = mConfig;
}
- virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
+ std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override {
return mPointerControllers[deviceId];
}
- virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
+ void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {
std::scoped_lock<std::mutex> lock(mLock);
mInputDevices = inputDevices;
mInputDevicesChanged = true;
mDevicesChangedCondition.notify_all();
}
- virtual std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
- const InputDeviceIdentifier&) {
+ std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
+ const InputDeviceIdentifier&) override {
return nullptr;
}
- virtual std::string getDeviceAlias(const InputDeviceIdentifier&) {
- return "";
- }
+ std::string getDeviceAlias(const InputDeviceIdentifier&) override { return ""; }
void waitForInputDevices(std::function<void(bool)> processDevicesChanged) {
std::unique_lock<std::mutex> lock(mLock);
@@ -592,29 +580,27 @@
return index >= 0 ? mDevices.valueAt(index) : nullptr;
}
- virtual Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const {
+ Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
Device* device = getDevice(deviceId);
return device ? device->classes : Flags<InputDeviceClass>(0);
}
- virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const {
+ InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
Device* device = getDevice(deviceId);
return device ? device->identifier : InputDeviceIdentifier();
}
- virtual int32_t getDeviceControllerNumber(int32_t) const {
- return 0;
- }
+ int32_t getDeviceControllerNumber(int32_t) const override { return 0; }
- virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
+ void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
Device* device = getDevice(deviceId);
if (device) {
*outConfiguration = device->configuration;
}
}
- virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
- RawAbsoluteAxisInfo* outAxisInfo) const {
+ status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const override {
Device* device = getDevice(deviceId);
if (device && device->enabled) {
ssize_t index = device->absoluteAxes.indexOfKey(axis);
@@ -627,7 +613,7 @@
return -1;
}
- virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
+ bool hasRelativeAxis(int32_t deviceId, int axis) const override {
Device* device = getDevice(deviceId);
if (device) {
return device->relativeAxes.indexOfKey(axis) >= 0;
@@ -635,13 +621,10 @@
return false;
}
- virtual bool hasInputProperty(int32_t, int) const {
- return false;
- }
+ bool hasInputProperty(int32_t, int) const override { return false; }
- virtual status_t mapKey(int32_t deviceId,
- int32_t scanCode, int32_t usageCode, int32_t metaState,
- int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const {
+ status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
+ int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
Device* device = getDevice(deviceId);
if (device) {
const KeyInfo* key = getKey(device, scanCode, usageCode);
@@ -677,15 +660,13 @@
return nullptr;
}
- virtual status_t mapAxis(int32_t, int32_t, AxisInfo*) const {
- return NAME_NOT_FOUND;
- }
+ status_t mapAxis(int32_t, int32_t, AxisInfo*) const override { return NAME_NOT_FOUND; }
- virtual void setExcludedDevices(const std::vector<std::string>& devices) {
+ void setExcludedDevices(const std::vector<std::string>& devices) override {
mExcludedDevices = devices;
}
- virtual size_t getEvents(int, RawEvent* buffer, size_t) {
+ size_t getEvents(int, RawEvent* buffer, size_t) override {
std::scoped_lock<std::mutex> lock(mLock);
if (mEvents.empty()) {
return 0;
@@ -697,7 +678,7 @@
return 1;
}
- virtual std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) {
+ std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override {
auto it = mVideoFrames.find(deviceId);
if (it != mVideoFrames.end()) {
std::vector<TouchVideoFrame> frames = std::move(it->second);
@@ -707,7 +688,7 @@
return {};
}
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
+ int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
@@ -718,7 +699,7 @@
return AKEY_STATE_UNKNOWN;
}
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
+ int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
@@ -729,7 +710,7 @@
return AKEY_STATE_UNKNOWN;
}
- virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const {
+ int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->switchStates.indexOfKey(sw);
@@ -740,8 +721,8 @@
return AKEY_STATE_UNKNOWN;
}
- virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
- int32_t* outValue) const {
+ status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
@@ -754,22 +735,22 @@
return -1;
}
- virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
- uint8_t* outFlags) const {
+ // Return true if the device has non-empty key layout.
+ bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) const override {
bool result = false;
Device* device = getDevice(deviceId);
if (device) {
+ result = device->keysByScanCode.size() > 0 || device->keysByUsageCode.size() > 0;
for (size_t i = 0; i < numCodes; i++) {
for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
outFlags[i] = 1;
- result = true;
}
}
for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
outFlags[i] = 1;
- result = true;
}
}
}
@@ -777,7 +758,7 @@
return result;
}
- virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const {
+ bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
@@ -786,12 +767,12 @@
return false;
}
- virtual bool hasLed(int32_t deviceId, int32_t led) const {
+ bool hasLed(int32_t deviceId, int32_t led) const override {
Device* device = getDevice(deviceId);
return device && device->leds.indexOfKey(led) >= 0;
}
- virtual void setLedState(int32_t deviceId, int32_t led, bool on) {
+ void setLedState(int32_t deviceId, int32_t led, bool on) override {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->leds.indexOfKey(led);
@@ -805,8 +786,8 @@
}
}
- virtual void getVirtualKeyDefinitions(int32_t deviceId,
- std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
+ void getVirtualKeyDefinitions(
+ int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {
outVirtualKeys.clear();
Device* device = getDevice(deviceId);
@@ -815,34 +796,29 @@
}
}
- virtual const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t) const {
+ const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t) const override {
return nullptr;
}
- virtual bool setKeyboardLayoutOverlay(int32_t, std::shared_ptr<KeyCharacterMap>) {
+ bool setKeyboardLayoutOverlay(int32_t, std::shared_ptr<KeyCharacterMap>) override {
return false;
}
- virtual void vibrate(int32_t, const VibrationElement&) {}
+ void vibrate(int32_t, const VibrationElement&) override {}
- virtual void cancelVibrate(int32_t) {
- }
+ void cancelVibrate(int32_t) override {}
virtual bool isExternal(int32_t) const {
return false;
}
- virtual void dump(std::string&) {
- }
+ void dump(std::string&) override {}
- virtual void monitor() {
- }
+ void monitor() override {}
- virtual void requestReopenDevices() {
- }
+ void requestReopenDevices() override {}
- virtual void wake() {
- }
+ void wake() override {}
};
// --- FakeInputMapper ---
@@ -874,7 +850,7 @@
mResetWasCalled(false),
mProcessWasCalled(false) {}
- virtual ~FakeInputMapper() { }
+ virtual ~FakeInputMapper() {}
void setKeyboardType(int32_t keyboardType) {
mKeyboardType = keyboardType;
@@ -943,11 +919,9 @@
}
private:
- virtual uint32_t getSources() {
- return mSources;
- }
+ uint32_t getSources() override { return mSources; }
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) {
+ void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
InputMapper::populateDeviceInfo(deviceInfo);
if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
@@ -955,7 +929,7 @@
}
}
- virtual void configure(nsecs_t, const InputReaderConfiguration* config, uint32_t changes) {
+ void configure(nsecs_t, const InputReaderConfiguration* config, uint32_t changes) override {
std::scoped_lock<std::mutex> lock(mLock);
mConfigureWasCalled = true;
@@ -968,45 +942,45 @@
mStateChangedCondition.notify_all();
}
- virtual void reset(nsecs_t) {
+ void reset(nsecs_t) override {
std::scoped_lock<std::mutex> lock(mLock);
mResetWasCalled = true;
mStateChangedCondition.notify_all();
}
- virtual void process(const RawEvent* rawEvent) {
+ void process(const RawEvent* rawEvent) override {
std::scoped_lock<std::mutex> lock(mLock);
mLastEvent = *rawEvent;
mProcessWasCalled = true;
mStateChangedCondition.notify_all();
}
- virtual int32_t getKeyCodeState(uint32_t, int32_t keyCode) {
+ int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
}
- virtual int32_t getScanCodeState(uint32_t, int32_t scanCode) {
+ int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
ssize_t index = mScanCodeStates.indexOfKey(scanCode);
return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
}
- virtual int32_t getSwitchState(uint32_t, int32_t switchCode) {
+ int32_t getSwitchState(uint32_t, int32_t switchCode) override {
ssize_t index = mSwitchStates.indexOfKey(switchCode);
return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
}
- virtual bool markSupportedKeyCodes(uint32_t, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- bool result = false;
+ // Return true if the device has non-empty key layout.
+ bool markSupportedKeyCodes(uint32_t, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) override {
for (size_t i = 0; i < numCodes; i++) {
for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
if (keyCodes[i] == mSupportedKeyCodes[j]) {
outFlags[i] = 1;
- result = true;
}
}
}
+ bool result = mSupportedKeyCodes.size() > 0;
return result;
}
@@ -1115,8 +1089,8 @@
protected:
sp<FakeInputReaderPolicy> mFakePolicy;
- virtual void SetUp() override { mFakePolicy = new FakeInputReaderPolicy(); }
- virtual void TearDown() override { mFakePolicy.clear(); }
+ void SetUp() override { mFakePolicy = new FakeInputReaderPolicy(); }
+ void TearDown() override { mFakePolicy.clear(); }
};
/**
@@ -1306,7 +1280,7 @@
std::shared_ptr<FakeEventHub> mFakeEventHub;
std::unique_ptr<InstrumentedInputReader> mReader;
- virtual void SetUp() override {
+ void SetUp() override {
mFakeEventHub = std::make_unique<FakeEventHub>();
mFakePolicy = new FakeInputReaderPolicy();
mFakeListener = new TestInputListener();
@@ -1315,7 +1289,7 @@
mFakeListener);
}
- virtual void TearDown() override {
+ void TearDown() override {
mFakeListener.clear();
mFakePolicy.clear();
}
@@ -1762,7 +1736,7 @@
sp<FakeInputReaderPolicy> mFakePolicy;
sp<InputReaderInterface> mReader;
- virtual void SetUp() override {
+ void SetUp() override {
mFakePolicy = new FakeInputReaderPolicy();
mTestListener = new TestInputListener(2000ms /*eventHappenedTimeout*/,
30ms /*eventDidNotHappenTimeout*/);
@@ -1777,7 +1751,7 @@
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
}
- virtual void TearDown() override {
+ void TearDown() override {
ASSERT_EQ(mReader->stop(), OK);
mTestListener.clear();
mFakePolicy.clear();
@@ -1891,7 +1865,7 @@
protected:
const std::string UNIQUE_ID = "local:0";
- virtual void SetUp() override {
+ void SetUp() override {
InputReaderIntegrationTest::SetUp();
// At least add an internal display.
setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
@@ -2035,7 +2009,7 @@
std::unique_ptr<InstrumentedInputReader> mReader;
std::shared_ptr<InputDevice> mDevice;
- virtual void SetUp() override {
+ void SetUp() override {
mFakeEventHub = std::make_unique<FakeEventHub>();
mFakePolicy = new FakeInputReaderPolicy();
mFakeListener = new TestInputListener();
@@ -2051,7 +2025,7 @@
mReader->loopOnce();
}
- virtual void TearDown() override {
+ void TearDown() override {
mFakeListener.clear();
mFakePolicy.clear();
}
@@ -2282,9 +2256,9 @@
mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
}
- virtual void SetUp() override { SetUp(DEVICE_CLASSES); }
+ void SetUp() override { SetUp(DEVICE_CLASSES); }
- virtual void TearDown() override {
+ void TearDown() override {
mFakeListener.clear();
mFakePolicy.clear();
}
@@ -2487,6 +2461,9 @@
const int32_t USAGE_UNKNOWN = 0x07ffff;
mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2588,6 +2565,9 @@
TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
@@ -2827,7 +2807,7 @@
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initial metastate to AMETA_NONE.
+ // Initialize metastate to AMETA_NUM_LOCK_ON.
ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
mapper.updateMetaState(AKEYCODE_NUM_LOCK);
@@ -2885,6 +2865,43 @@
ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
}
+TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
+ mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
+
+ KeyboardInputMapper& mapper =
+ addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
+
+ // Initial metastate should be AMETA_NONE as no meta keys added.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
+ // Meta state should be AMETA_NONE after reset
+ mapper.reset(ARBITRARY_TIME);
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
+ // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
+ mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
+
+ NotifyKeyArgs args;
+ // Press button "A"
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_A, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(AMETA_NONE, args.metaState);
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+ ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
+
+ // Button up.
+ process(mapper, ARBITRARY_TIME + 2, EV_KEY, BTN_A, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(AMETA_NONE, args.metaState);
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+ ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
+}
+
TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
// keyboard 1.
mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
@@ -3034,9 +3051,7 @@
class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
protected:
- virtual void SetUp() override {
- InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL);
- }
+ void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
};
TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
@@ -3124,7 +3139,7 @@
std::shared_ptr<FakePointerController> mFakePointerController;
- virtual void SetUp() override {
+ void SetUp() override {
InputMapperTest::SetUp();
mFakePointerController = std::make_shared<FakePointerController>();
@@ -7458,9 +7473,7 @@
class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
protected:
- virtual void SetUp() override {
- InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL);
- }
+ void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
};
/**
diff --git a/services/powermanager/benchmarks/AndroidTest.xml b/services/powermanager/benchmarks/AndroidTest.xml
deleted file mode 100644
index 40f4872..0000000
--- a/services/powermanager/benchmarks/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 libpowermanager benchmarks">
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="libpowermanager_benchmarks->/data/benchmarktest/benchmark" />
- </target_preparer>
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-metric-instrumentation" />
- <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
- <option name="native-benchmark-device-path" value="/data/benchmarktest" />
- <option name="benchmark-module-name" value="benchmark" />
- </test>
-</configuration>
diff --git a/services/powermanager/tests/IThermalManagerTest.cpp b/services/powermanager/tests/IThermalManagerTest.cpp
index 575b9ee..b62be5f 100644
--- a/services/powermanager/tests/IThermalManagerTest.cpp
+++ b/services/powermanager/tests/IThermalManagerTest.cpp
@@ -86,12 +86,14 @@
EXPECT_NE(binder, nullptr);
mThermalSvc = interface_cast<IThermalService>(binder);
EXPECT_NE(mThermalSvc, nullptr);
+ // Lock mutex for operation, so listener will only be processed after wait_for is called
+ std::unique_lock<std::mutex> lock(mMutex);
bool success = false;
binder::Status ret = mThermalSvc->registerThermalStatusListener(this, &success);
+ // Check the result
ASSERT_TRUE(success);
ASSERT_TRUE(ret.isOk());
// Wait for listener called after registration, shouldn't timeout
- std::unique_lock<std::mutex> lock(mMutex);
EXPECT_NE(mCondition.wait_for(lock, 1s), std::cv_status::timeout);
}
@@ -111,6 +113,7 @@
TEST_P(IThermalListenerTest, TestListener) {
int level = GetParam();
+ // Lock mutex for operation, so listener will only be processed after wait_for is called
std::unique_lock<std::mutex> lock(mMutex);
// Set the override thermal status
setThermalOverride(level);
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 6ba1942..4dc20c4 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -29,6 +29,7 @@
#include <compositionengine/impl/OutputCompositionState.h>
#include <cutils/properties.h>
#include <gui/IRegionSamplingListener.h>
+#include <gui/SyncScreenCaptureListener.h>
#include <ui/DisplayStatInfo.h>
#include <utils/Trace.h>
@@ -446,9 +447,10 @@
PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
}
- ScreenCaptureResults captureResults;
+ const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
- true /* regionSampling */, captureResults);
+ true /* regionSampling */, captureListener);
+ ScreenCaptureResults captureResults = captureListener->waitForResults();
std::vector<Descriptor> activeDescriptors;
for (const auto& descriptor : descriptors) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5400365..98d1552 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -52,7 +52,6 @@
#include <errno.h>
#include <gui/BufferQueue.h>
#include <gui/DebugEGLImageTracker.h>
-#include <gui/GuiConfig.h>
#include <gui/IDisplayEventConnection.h>
#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
@@ -75,7 +74,6 @@
#include <ui/DisplayState.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
-#include <ui/UiConfig.h>
#include <utils/StopWatch.h>
#include <utils/String16.h>
#include <utils/String8.h>
@@ -4725,8 +4723,6 @@
result.append("Build configuration:");
colorizer.reset(result);
appendSfConfigString(result);
- appendUiConfigString(result);
- appendGuiConfigString(result);
result.append("\n");
result.append("\nDisplay identification data:\n");
@@ -4824,9 +4820,10 @@
const auto activeConfig = getHwComposer().getActiveConfig(*displayId);
std::string fps, xDpi, yDpi;
if (activeConfig) {
- fps = std::to_string(1e9 / getHwComposer().getDisplayVsyncPeriod(*displayId)) + " fps";
- xDpi = activeConfig->getDpiX();
- yDpi = activeConfig->getDpiY();
+ fps = base::StringPrintf("%.2f Hz",
+ 1e9f / getHwComposer().getDisplayVsyncPeriod(*displayId));
+ xDpi = base::StringPrintf("%.2f", activeConfig->getDpiX());
+ yDpi = base::StringPrintf("%.2f", activeConfig->getDpiY());
} else {
fps = "unknown";
xDpi = "unknown";
@@ -5530,12 +5527,9 @@
auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
traverseLayersInLayerStack(layerStack, args.uid, visitor);
};
- ScreenCaptureResults captureResults;
- status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
- args.pixelFormat, captureResults);
- captureResults.result = status;
- captureListener->onScreenCaptureComplete(captureResults);
- return status;
+
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+ args.pixelFormat, captureListener);
}
status_t SurfaceFlinger::setSchedFifo(bool enabled) {
@@ -5608,12 +5602,8 @@
traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
};
- ScreenCaptureResults captureResults;
- status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
- ui::PixelFormat::RGBA_8888, captureResults);
- captureResults.result = status;
- captureListener->onScreenCaptureComplete(captureResults);
- return status;
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
+ ui::PixelFormat::RGBA_8888, captureListener);
}
status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
@@ -5704,7 +5694,7 @@
captureSecureLayers);
});
- auto traverseLayers = [parent, args, &excludeLayers](const LayerVector::Visitor& visitor) {
+ auto traverseLayers = [parent, args, excludeLayers](const LayerVector::Visitor& visitor) {
parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
if (!layer->isVisible()) {
return;
@@ -5726,18 +5716,14 @@
});
};
- ScreenCaptureResults captureResults;
- status_t status = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
- args.pixelFormat, captureResults);
- captureResults.result = status;
- captureListener->onScreenCaptureComplete(captureResults);
- return status;
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+ args.pixelFormat, captureListener);
}
status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
TraverseLayersFunction traverseLayers,
ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
- ScreenCaptureResults& captureResults) {
+ const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
// TODO(b/116112787) Make buffer usage a parameter.
@@ -5747,54 +5733,56 @@
getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
static_cast<android_pixel_format>(reqPixelFormat),
1 /* layerCount */, usage, "screenshot");
-
return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
- false /* regionSampling */, captureResults);
+ false /* regionSampling */, captureListener);
}
status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool regionSampling,
- ScreenCaptureResults& captureResults) {
+ sp<GraphicBuffer>& buffer, bool regionSampling,
+ const sp<IScreenCaptureListener>& captureListener) {
+ ATRACE_CALL();
+
+ if (captureListener == nullptr) {
+ ALOGE("capture screen must provide a capture listener callback");
+ return BAD_VALUE;
+ }
+
const int uid = IPCThreadState::self()->getCallingUid();
const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
- status_t result;
- int syncFd;
+ static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable {
+ if (mRefreshPending) {
+ ALOGW("Skipping screenshot for now");
+ captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, regionSampling,
+ captureListener);
+ return;
+ }
+ ScreenCaptureResults captureResults;
+ std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get();
+ if (!renderArea) {
+ ALOGW("Skipping screen capture because of invalid render area.");
+ captureResults.result = NO_MEMORY;
+ captureListener->onScreenCaptureComplete(captureResults);
+ return;
+ }
- do {
- std::tie(result, syncFd) =
- schedule([&]() -> std::pair<status_t, int> {
- if (mRefreshPending) {
- ALOGW("Skipping screenshot for now");
- return {EAGAIN, -1};
- }
- std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get();
- if (!renderArea) {
- ALOGW("Skipping screen capture because of invalid render area.");
- return {NO_MEMORY, -1};
- }
+ status_t result = NO_ERROR;
+ int syncFd = -1;
+ renderArea->render([&] {
+ result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem, &syncFd,
+ regionSampling, captureResults);
+ });
- status_t result = NO_ERROR;
- int fd = -1;
+ if (result == NO_ERROR) {
+ sync_wait(syncFd, -1);
+ close(syncFd);
+ }
+ captureResults.result = result;
+ captureListener->onScreenCaptureComplete(captureResults);
+ }));
- Mutex::Autolock lock(mStateLock);
- renderArea->render([&] {
- result = renderScreenImplLocked(*renderArea, traverseLayers, buffer.get(),
- forSystem, &fd, regionSampling,
- captureResults);
- });
-
- return {result, fd};
- }).get();
- } while (result == EAGAIN);
-
- if (result == NO_ERROR) {
- sync_wait(syncFd, -1);
- close(syncFd);
- }
-
- return result;
+ return NO_ERROR;
}
status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0d54c3e..33ec25d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -781,14 +781,14 @@
// Boot animation, on/off animations and screen capture
void startBootAnim();
- status_t renderScreenImplLocked(const RenderArea& renderArea,
- TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool forSystem, int* outSyncFd,
- bool regionSampling, ScreenCaptureResults& captureResults);
+ status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
+ const sp<GraphicBuffer>&, bool forSystem, int* outSyncFd,
+ bool regionSampling, ScreenCaptureResults&);
status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize,
- ui::PixelFormat, ScreenCaptureResults& captureResults);
- status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, const sp<GraphicBuffer>&,
- bool regionSampling, ScreenCaptureResults& captureResults);
+ ui::PixelFormat, const sp<IScreenCaptureListener>&);
+ status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp<GraphicBuffer>&,
+ bool regionSampling, const sp<IScreenCaptureListener>&);
+
sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index fbf5ecf..167d777 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -15,32 +15,16 @@
*/
#pragma once
+#include <gui/SyncScreenCaptureListener.h>
#include <ui/Rect.h>
#include <utils/String8.h>
#include <functional>
-#include <future>
#include "TransactionUtils.h"
namespace android {
namespace {
-class SyncScreenCaptureListener : public BnScreenCaptureListener {
-public:
- status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override {
- resultsPromise.set_value(captureResults);
- return NO_ERROR;
- }
-
- ScreenCaptureResults waitForResults() {
- std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
- return resultsFuture.get();
- }
-
-private:
- std::promise<ScreenCaptureResults> resultsPromise;
-};
-
// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
// individual pixel values for testing purposes.
class ScreenCapture : public RefBase {
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index ce20aeb..9672644 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -501,6 +501,10 @@
}
if (externalControlResult.withDefault(false)) {
capabilities |= Capabilities::EXTERNAL_CONTROL;
+
+ if (amplitudeResult.withDefault(false)) {
+ capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL;
+ }
}
return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp
new file mode 100644
index 0000000..c1a03a1
--- /dev/null
+++ b/services/vibratorservice/benchmarks/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_benchmark {
+ name: "libvibratorservice_benchmarks",
+ srcs: [
+ "VibratorHalControllerBenchmarks.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "libvibratorservice",
+ "android.hardware.vibrator-cpp",
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hardware.vibrator@1.3",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
diff --git a/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp b/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp
new file mode 100644
index 0000000..0d4c55e
--- /dev/null
+++ b/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PowerHalControllerBenchmarks"
+
+#include <benchmark/benchmark.h>
+#include <vibratorservice/VibratorHalController.h>
+
+using ::android::enum_range;
+using ::benchmark::Counter;
+using ::benchmark::Fixture;
+using ::benchmark::kMicrosecond;
+using ::benchmark::State;
+using ::benchmark::internal::Benchmark;
+
+using namespace android;
+using namespace std::chrono_literals;
+
+class VibratorBench : public Fixture {
+public:
+ void SetUp(State& /*state*/) override { mController.init(); }
+
+ void TearDown(State& /*state*/) override { mController.off(); }
+
+ static void DefaultConfig(Benchmark* b) { b->Unit(kMicrosecond); }
+
+ static void DefaultArgs(Benchmark* /*b*/) {
+ // none
+ }
+
+protected:
+ vibrator::HalController mController;
+
+ auto getOtherArg(const State& state, std::size_t index) const { return state.range(index + 0); }
+
+ bool hasCapabilities(vibrator::HalResult<vibrator::Capabilities> result,
+ vibrator::Capabilities query) {
+ if (!result.isOk()) {
+ return false;
+ }
+ return (result.value() & query) == query;
+ }
+};
+
+#define BENCHMARK_WRAPPER(fixt, test, code) \
+ BENCHMARK_DEFINE_F(fixt, test) \
+ /* NOLINTNEXTLINE */ \
+ (State& state){code} BENCHMARK_REGISTER_F(fixt, test) \
+ ->Apply(fixt::DefaultConfig) \
+ ->Apply(fixt::DefaultArgs)
+
+BENCHMARK_WRAPPER(VibratorBench, init, {
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ state.ResumeTiming();
+ controller.init();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, initCached, {
+ for (auto _ : state) {
+ mController.init();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, ping, {
+ for (auto _ : state) {
+ mController.ping();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, tryReconnect, {
+ for (auto _ : state) {
+ mController.tryReconnect();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, on, {
+ auto duration = 60s;
+ auto callback = []() {};
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mController.on(duration, callback);
+ state.PauseTiming();
+ mController.off();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, off, {
+ auto duration = 60s;
+ auto callback = []() {};
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ mController.on(duration, callback);
+ state.ResumeTiming();
+ mController.off();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, setAmplitude, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::AMPLITUDE_CONTROL)) {
+ return;
+ }
+
+ auto duration = 60s;
+ auto callback = []() {};
+ auto amplitude = UINT8_MAX;
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ controller.init();
+ controller.on(duration, callback);
+ state.ResumeTiming();
+ controller.setAmplitude(amplitude);
+ state.PauseTiming();
+ controller.off();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, setAmplitudeCached, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::AMPLITUDE_CONTROL)) {
+ return;
+ }
+
+ auto duration = 6000s;
+ auto callback = []() {};
+ auto amplitude = UINT8_MAX;
+
+ mController.on(duration, callback);
+
+ for (auto _ : state) {
+ mController.setAmplitude(amplitude);
+ }
+
+ mController.off();
+});
+
+BENCHMARK_WRAPPER(VibratorBench, setExternalControl, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::EXTERNAL_CONTROL)) {
+ return;
+ }
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ controller.init();
+ state.ResumeTiming();
+ controller.setExternalControl(true);
+ state.PauseTiming();
+ controller.setExternalControl(false);
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, setExternalControlCached, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::EXTERNAL_CONTROL)) {
+ return;
+ }
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mController.setExternalControl(true);
+ state.PauseTiming();
+ mController.setExternalControl(false);
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, setExternalAmplitudeCached, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::EXTERNAL_AMPLITUDE_CONTROL)) {
+ return;
+ }
+
+ auto amplitude = UINT8_MAX;
+
+ mController.setExternalControl(true);
+
+ for (auto _ : state) {
+ mController.setAmplitude(amplitude);
+ }
+
+ mController.setExternalControl(false);
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getCapabilities, {
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ controller.init();
+ state.ResumeTiming();
+ controller.getCapabilities();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getCapabilitiesCached, {
+ // First call to cache values.
+ mController.getCapabilities();
+
+ for (auto _ : state) {
+ mController.getCapabilities();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getSupportedEffects, {
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ controller.init();
+ state.ResumeTiming();
+ controller.getSupportedEffects();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getSupportedEffectsCached, {
+ // First call to cache values.
+ mController.getSupportedEffects();
+
+ for (auto _ : state) {
+ mController.getSupportedEffects();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getSupportedPrimitives, {
+ for (auto _ : state) {
+ state.PauseTiming();
+ vibrator::HalController controller;
+ controller.init();
+ state.ResumeTiming();
+ controller.getSupportedPrimitives();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench, getSupportedPrimitivesCached, {
+ // First call to cache values.
+ mController.getSupportedPrimitives();
+
+ for (auto _ : state) {
+ mController.getSupportedPrimitives();
+ }
+});
+
+class VibratorEffectsBench : public VibratorBench {
+public:
+ static void DefaultArgs(Benchmark* b) {
+ vibrator::HalController controller;
+ auto effectsResult = controller.getSupportedEffects();
+ if (!effectsResult.isOk()) {
+ return;
+ }
+
+ std::vector<hardware::vibrator::Effect> supported = effectsResult.value();
+ b->ArgNames({"Effect", "Strength"});
+ for (const auto& effect : enum_range<hardware::vibrator::Effect>()) {
+ if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
+ continue;
+ }
+ for (const auto& strength : enum_range<hardware::vibrator::EffectStrength>()) {
+ b->Args({static_cast<long>(effect), static_cast<long>(strength)});
+ }
+ }
+ }
+
+protected:
+ auto getEffect(const State& state) const {
+ return static_cast<hardware::vibrator::Effect>(this->getOtherArg(state, 0));
+ }
+
+ auto getStrength(const State& state) const {
+ return static_cast<hardware::vibrator::EffectStrength>(this->getOtherArg(state, 1));
+ }
+};
+
+BENCHMARK_WRAPPER(VibratorEffectsBench, alwaysOnEnable, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::ALWAYS_ON_CONTROL)) {
+ return;
+ }
+
+ int32_t id = 1;
+ auto effect = getEffect(state);
+ auto strength = getStrength(state);
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mController.alwaysOnEnable(id, effect, strength);
+ state.PauseTiming();
+ mController.alwaysOnDisable(id);
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorEffectsBench, alwaysOnDisable, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::ALWAYS_ON_CONTROL)) {
+ return;
+ }
+
+ int32_t id = 1;
+ auto effect = getEffect(state);
+ auto strength = getStrength(state);
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ mController.alwaysOnEnable(id, effect, strength);
+ state.ResumeTiming();
+ mController.alwaysOnDisable(id);
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorEffectsBench, performEffect, {
+ auto effect = getEffect(state);
+ auto strength = getStrength(state);
+ auto callback = []() {};
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mController.performEffect(effect, strength, callback);
+ state.PauseTiming();
+ mController.off();
+ }
+});
+
+class VibratorPrimitivesBench : public VibratorBench {
+public:
+ static void DefaultArgs(Benchmark* b) {
+ vibrator::HalController controller;
+ auto primitivesResult = controller.getSupportedPrimitives();
+ if (!primitivesResult.isOk()) {
+ return;
+ }
+
+ std::vector<hardware::vibrator::CompositePrimitive> supported = primitivesResult.value();
+ b->ArgNames({"Primitive"});
+ for (const auto& primitive : enum_range<hardware::vibrator::CompositePrimitive>()) {
+ if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) {
+ continue;
+ }
+ b->Args({static_cast<long>(primitive)});
+ }
+ }
+
+protected:
+ auto getPrimitive(const State& state) const {
+ return static_cast<hardware::vibrator::CompositePrimitive>(this->getOtherArg(state, 0));
+ }
+};
+
+BENCHMARK_WRAPPER(VibratorPrimitivesBench, performComposedEffect, {
+ auto capabilitiesResult = mController.getCapabilities();
+
+ if (!hasCapabilities(capabilitiesResult, vibrator::Capabilities::COMPOSE_EFFECTS)) {
+ return;
+ }
+
+ hardware::vibrator::CompositeEffect effect;
+ effect.primitive = getPrimitive(state);
+ effect.scale = 1.0f;
+ effect.delayMs = 0;
+
+ std::vector<hardware::vibrator::CompositeEffect> effects;
+ effects.push_back(effect);
+ auto callback = []() {};
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mController.performComposedEffect(effects, callback);
+ state.PauseTiming();
+ mController.off();
+ }
+});
+
+BENCHMARK_MAIN();
\ No newline at end of file
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
index 5de6257..08652f4 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
@@ -118,7 +118,8 @@
auto result = mWrapper->getCapabilities();
ASSERT_TRUE(result.isOk());
- ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL | vibrator::Capabilities::EXTERNAL_CONTROL,
+ ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL | vibrator::Capabilities::EXTERNAL_CONTROL |
+ vibrator::Capabilities::EXTERNAL_AMPLITUDE_CONTROL,
result.value());
}