Merge "Revert "Revert "[SurfaceFlinger] Add GPU protected content support."""
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 2e9701f..854244f 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -139,7 +139,16 @@
srcs: ["otapreopt_chroot.cpp"],
shared_libs: [
"libbase",
+ "libjsoncpp",
"liblog",
+ "libselinux",
+ "libziparchive",
+ ],
+ static_libs: [
+ "libapex",
+ "libapexd",
+ "libavb",
+ "libdm",
],
}
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index e90cf3b..a3dfa2d 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <linux/unistd.h>
#include <sys/mount.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <sstream>
@@ -24,6 +25,9 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
+#include <selinux/android.h>
+
+#include <apexd.h>
#include "installd_constants.h"
#include "otapreopt_utils.h"
@@ -138,6 +142,32 @@
UNUSED(product_result);
}
+ // Setup APEX mount point and its security context.
+ // The logic here is similar to the one in system/core/rootdir/init.rc:
+ //
+ // mount tmpfs tmpfs /apex nodev noexec nosuid
+ // chmod 0755 /apex
+ // chown root root /apex
+ // restorecon /apex
+ //
+ if (mount("tmpfs", "/postinstall/apex", "tmpfs", MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr)
+ != 0) {
+ PLOG(ERROR) << "Failed to mount tmpfs in /postinstall/apex";
+ exit(209);
+ }
+ if (chmod("/postinstall/apex", 0755) != 0) {
+ PLOG(ERROR) << "Failed to chmod /postinstall/apex to 0755";
+ exit(210);
+ }
+ if (chown("/postinstall/apex", 0, 0) != 0) {
+ PLOG(ERROR) << "Failed to chown /postinstall/apex to root:root";
+ exit(211);
+ }
+ if (selinux_android_restorecon("/postinstall/apex", 0) < 0) {
+ PLOG(ERROR) << "Failed to restorecon /postinstall/apex";
+ exit(212);
+ }
+
// Chdir into /postinstall.
if (chdir("/postinstall") != 0) {
PLOG(ERROR) << "Unable to chdir into /postinstall.";
@@ -155,6 +185,18 @@
exit(205);
}
+ // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
+ // the Android Runtime APEX, as it is required by otapreopt to run dex2oat.
+ {
+ // The logic here is (partially) copied and adapted from
+ // system/apex/apexd/apexd_main.cpp.
+
+ // Only scan the APEX directory under /system (within the chroot dir).
+ // Note that this leaves around the loop devices created and used by
+ // libapexd's code, but this is fine, as we expect to reboot soon after.
+ apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
+ }
+
// Now go on and run otapreopt.
// Incoming: cmd + status-fd + target-slot + cmd... + null | Incoming | = argc + 1
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index a6d7a78..c706d91 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -376,23 +376,23 @@
}
mServicesTable.setDescription(
- "All binderized services (registered services through hwservicemanager)");
+ "| All binderized services (registered with hwservicemanager)");
mPassthroughRefTable.setDescription(
- "All interfaces that getService() has ever return as a passthrough interface;\n"
- "PIDs / processes shown below might be inaccurate because the process\n"
- "might have relinquished the interface or might have died.\n"
- "The Server / Server CMD column can be ignored.\n"
- "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
- "the library and successfully fetched the passthrough implementation.");
+ "| All interfaces that getService() has ever returned as a passthrough interface;\n"
+ "| PIDs / processes shown below might be inaccurate because the process\n"
+ "| might have relinquished the interface or might have died.\n"
+ "| The Server / Server CMD column can be ignored.\n"
+ "| The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
+ "| the library and successfully fetched the passthrough implementation.");
mImplementationsTable.setDescription(
- "All available passthrough implementations (all -impl.so files).\n"
- "These may return subclasses through their respective HIDL_FETCH_I* functions.");
+ "| All available passthrough implementations (all -impl.so files).\n"
+ "| These may return subclasses through their respective HIDL_FETCH_I* functions.");
mManifestHalsTable.setDescription(
- "All HALs that are in VINTF manifest.");
+ "| All HALs that are in VINTF manifest.");
mLazyHalsTable.setDescription(
- "All HALs that are declared in VINTF manifest:\n"
- " - as hwbinder HALs but are not registered to hwservicemanager, and\n"
- " - as hwbinder/passthrough HALs with no implementation.");
+ "| All HALs that are declared in VINTF manifest:\n"
+ "| - as hwbinder HALs but are not registered to hwservicemanager, and\n"
+ "| - as hwbinder/passthrough HALs with no implementation.");
}
bool ListCommand::addEntryWithInstance(const TableEntry& entry,
@@ -972,10 +972,10 @@
thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
return OK;
}, "print VINTF info. This column contains a comma-separated list of:\n"
- " - DM: device manifest\n"
- " - DC: device compatibility matrix\n"
- " - FM: framework manifest\n"
- " - FC: framework compatibility matrix"});
+ " - DM: if the HAL is in the device manifest\n"
+ " - DC: if the HAL is in the device compatibility matrix\n"
+ " - FM: if the HAL is in the framework manifest\n"
+ " - FC: if the HAL is in the framework compatibility matrix"});
mOptions.push_back({'S', "service-status", no_argument, v++, [](ListCommand* thiz, const char*) {
thiz->mSelectedColumns.push_back(TableColumnType::SERVICE_STATUS);
return OK;
@@ -1054,7 +1054,7 @@
return OK;
}, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
"section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
- "passthrough_libs), and (v|vintf).\nDefault is `bcl`."});
+ "passthrough_libs), (v|vintf), and (z|lazy).\nDefault is `bcl`."});
}
// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
@@ -1150,7 +1150,7 @@
}
if (mSelectedColumns.empty()) {
- mSelectedColumns = {TableColumnType::RELEASED,
+ mSelectedColumns = {TableColumnType::VINTF, TableColumnType::RELEASED,
TableColumnType::INTERFACE_NAME, TableColumnType::THREADS,
TableColumnType::SERVER_PID, TableColumnType::CLIENT_PIDS};
}
@@ -1210,7 +1210,7 @@
err() << "list:" << std::endl
<< " lshal" << std::endl
<< " lshal list" << std::endl
- << " List all hals with default ordering and columns (`lshal list -liepc`)" << std::endl
+ << " List all hals with default ordering and columns (`lshal list -Vliepc`)" << std::endl
<< " lshal list [-h|--help]" << std::endl
<< " -h, --help: Print help message for list (`lshal help list`)" << std::endl
<< " lshal [list] [OPTIONS...]" << std::endl;
diff --git a/cmds/rss_hwm_reset/Android.bp b/cmds/rss_hwm_reset/Android.bp
new file mode 100644
index 0000000..15f10ef
--- /dev/null
+++ b/cmds/rss_hwm_reset/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 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
+//
+// https://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_binary {
+ name: "rss_hwm_reset",
+
+ srcs: [
+ "rss_hwm_reset.cc",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+
+ init_rc: ["rss_hwm_reset.rc"],
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.cc b/cmds/rss_hwm_reset/rss_hwm_reset.cc
new file mode 100644
index 0000000..1626e7e
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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
+ *
+ * https://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.
+ */
+
+ /*
+ * rss_hwm_reset clears the RSS high-water mark counters for all currently
+ * running processes. It writes "5" to /proc/PID/clear_refs for every PID.
+ *
+ * It runs in its own process becuase dac_override capability is required
+ * in order to write to other processes' clear_refs.
+ *
+ * It is invoked from a system service by flipping sys.rss_hwm_reset.on
+ * property to "1".
+ */
+
+#define LOG_TAG "rss_hwm_reset"
+
+#include <dirent.h>
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+
+namespace {
+// Resets RSS HWM counter for the selected process by writing 5 to
+// /proc/PID/clear_refs.
+void reset_rss_hwm(const char* pid) {
+ std::string clear_refs_path =
+ ::android::base::StringPrintf("/proc/%s/clear_refs", pid);
+ ::android::base::WriteStringToFile("5", clear_refs_path);
+}
+}
+
+// Clears RSS HWM counters for all currently running processes.
+int main(int /* argc */, char** /* argv[] */) {
+ DIR* dirp = opendir("/proc");
+ if (dirp == nullptr) {
+ ALOGE("unable to read /proc");
+ return 1;
+ }
+ struct dirent* entry;
+ while ((entry = readdir(dirp)) != nullptr) {
+ // Skip entries that are not directories.
+ if (entry->d_type != DT_DIR) continue;
+ // Skip entries that do not contain only numbers.
+ const char* pid = entry->d_name;
+ while (*pid) {
+ if (*pid < '0' || *pid > '9') break;
+ pid++;
+ }
+ if (*pid != 0) continue;
+
+ pid = entry->d_name;
+ reset_rss_hwm(pid);
+ }
+ closedir(dirp);
+ return 0;
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.rc b/cmds/rss_hwm_reset/rss_hwm_reset.rc
new file mode 100644
index 0000000..fbbc820
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.rc
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 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
+#
+# https://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.
+
+service rss_hwm_reset /system/bin/rss_hwm_reset
+ class late_start
+ disabled
+ oneshot
+ user nobody
+ group nobody readproc
+ writepid /dev/cpuset/system-background/tasks
+ capabilities DAC_OVERRIDE
+
+on property:sys.rss_hwm_reset.on=1
+ start rss_hwm_reset
+ setprop sys.rss_hwm_reset.on 0
diff --git a/data/etc/android.hardware.face.xml b/data/etc/android.hardware.biometrics.face.xml
similarity index 93%
rename from data/etc/android.hardware.face.xml
rename to data/etc/android.hardware.biometrics.face.xml
index abd23fb..7fa0bf9 100644
--- a/data/etc/android.hardware.face.xml
+++ b/data/etc/android.hardware.biometrics.face.xml
@@ -16,5 +16,5 @@
<!-- This is the standard set of features for a biometric face authentication sensor. -->
<permissions>
- <feature name="android.hardware.face" />
+ <feature name="android.hardware.biometrics.face" />
</permissions>
diff --git a/data/etc/android.hardware.biometrics.fingerprint.xml b/data/etc/android.hardware.biometrics.fingerprint.xml
new file mode 100644
index 0000000..e5af541
--- /dev/null
+++ b/data/etc/android.hardware.biometrics.fingerprint.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2018 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!-- This is the standard set of features for a biometric fingerprint sensor. -->
+<permissions>
+ <feature name="android.hardware.biometrics.fingerprint" />
+</permissions>
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index f23ed5d..ae04b0f 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1446,7 +1446,7 @@
}
IPCThreadState::self()->flushCommands(); // flush BC_ENTER_LOOPER
- epoll_fd = epoll_create1(0);
+ epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
return 1;
}
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
index ed773e0..16952a6 100644
--- a/libs/gui/BufferHubProducer.cpp
+++ b/libs/gui/BufferHubProducer.cpp
@@ -520,7 +520,7 @@
}
auto buffer_producer = buffers_[slot].mBufferProducer;
- queue_->Enqueue(buffer_producer, size_t(slot), 0ULL);
+ queue_->Enqueue(buffer_producer, size_t(slot), 0U);
buffers_[slot].mBufferState.cancel();
buffers_[slot].mFence = fence;
ALOGV("cancelBuffer: slot %d", slot);
diff --git a/libs/sensorprivacy/Android.bp b/libs/sensorprivacy/Android.bp
new file mode 100644
index 0000000..e0e3469
--- /dev/null
+++ b/libs/sensorprivacy/Android.bp
@@ -0,0 +1,47 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+ name: "libsensorprivacy",
+
+ aidl: {
+ export_aidl_headers: true,
+ local_include_dirs: ["aidl"],
+ },
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wzero-as-null-pointer-constant",
+ ],
+
+ srcs: [
+ "aidl/android/hardware/ISensorPrivacyListener.aidl",
+ "aidl/android/hardware/ISensorPrivacyManager.aidl",
+ "SensorPrivacyManager.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libcutils",
+ "libutils",
+ "liblog",
+ "libhardware",
+ ],
+
+ export_include_dirs: ["include"],
+
+ export_shared_lib_headers: ["libbinder"],
+}
diff --git a/libs/sensorprivacy/SensorPrivacyManager.cpp b/libs/sensorprivacy/SensorPrivacyManager.cpp
new file mode 100644
index 0000000..1da79a0
--- /dev/null
+++ b/libs/sensorprivacy/SensorPrivacyManager.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 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 <mutex>
+#include <unistd.h>
+
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
+
+#include <utils/SystemClock.h>
+
+namespace android {
+
+SensorPrivacyManager::SensorPrivacyManager()
+{
+}
+
+sp<hardware::ISensorPrivacyManager> SensorPrivacyManager::getService()
+{
+ std::lock_guard<Mutex> scoped_lock(mLock);
+ int64_t startTime = 0;
+ sp<hardware::ISensorPrivacyManager> service = mService;
+ while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
+ sp<IBinder> binder = defaultServiceManager()->checkService(String16("sensor_privacy"));
+ if (binder == nullptr) {
+ // Wait for the sensor privacy service to come back...
+ if (startTime == 0) {
+ startTime = uptimeMillis();
+ ALOGI("Waiting for sensor privacy service");
+ } else if ((uptimeMillis() - startTime) > 1000000) {
+ ALOGW("Waiting too long for sensor privacy service, giving up");
+ service = nullptr;
+ break;
+ }
+ usleep(25000);
+ } else {
+ service = interface_cast<hardware::ISensorPrivacyManager>(binder);
+ mService = service;
+ }
+ }
+ return service;
+}
+
+void SensorPrivacyManager::addSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& listener)
+{
+ sp<hardware::ISensorPrivacyManager> service = getService();
+ if (service != nullptr) {
+ service->addSensorPrivacyListener(listener);
+ }
+}
+
+void SensorPrivacyManager::removeSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& listener)
+{
+ sp<hardware::ISensorPrivacyManager> service = getService();
+ if (service != nullptr) {
+ service->removeSensorPrivacyListener(listener);
+ }
+}
+
+bool SensorPrivacyManager::isSensorPrivacyEnabled()
+{
+ sp<hardware::ISensorPrivacyManager> service = getService();
+ if (service != nullptr) {
+ bool result;
+ service->isSensorPrivacyEnabled(&result);
+ return result;
+ }
+ // if the SensorPrivacyManager is not available then assume sensor privacy is disabled
+ return false;
+}
+
+}; // namespace android
diff --git a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl
new file mode 100644
index 0000000..58177d8
--- /dev/null
+++ b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+/**
+ * @hide
+ */
+oneway interface ISensorPrivacyListener {
+ void onSensorPrivacyChanged(boolean enabled);
+}
diff --git a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl
new file mode 100644
index 0000000..4c2d5db
--- /dev/null
+++ b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.hardware.ISensorPrivacyListener;
+
+/** @hide */
+interface ISensorPrivacyManager {
+ void addSensorPrivacyListener(in ISensorPrivacyListener listener);
+
+ void removeSensorPrivacyListener(in ISensorPrivacyListener listener);
+
+ boolean isSensorPrivacyEnabled();
+
+ void setSensorPrivacy(boolean enable);
+}
diff --git a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
new file mode 100644
index 0000000..8826595
--- /dev/null
+++ b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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_SENSOR_PRIVACY_MANAGER_H
+#define ANDROID_SENSOR_PRIVACY_MANAGER_H
+
+#include "android/hardware/ISensorPrivacyListener.h"
+#include "android/hardware/ISensorPrivacyManager.h"
+
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class SensorPrivacyManager
+{
+public:
+ SensorPrivacyManager();
+
+ void addSensorPrivacyListener(const sp<hardware::ISensorPrivacyListener>& listener);
+ void removeSensorPrivacyListener(const sp<hardware::ISensorPrivacyListener>& listener);
+ bool isSensorPrivacyEnabled();
+
+private:
+ Mutex mLock;
+ sp<hardware::ISensorPrivacyManager> mService;
+ sp<hardware::ISensorPrivacyManager> getService();
+};
+
+
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SENSOR_PRIVACY_MANAGER_H
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 1464e48..226b6ee 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -95,22 +95,21 @@
BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
uint32_t format, uint64_t usage, size_t mUserMetadataSize) {
ATRACE_CALL();
- ALOGD("BufferHubBuffer::BufferHubBuffer: width=%u height=%u layerCount=%u, format=%u "
- "usage=%" PRIx64 " mUserMetadataSize=%zu",
- width, height, layerCount, format, usage, mUserMetadataSize);
+ ALOGD("%s: width=%u height=%u layerCount=%u, format=%u usage=%" PRIx64 " mUserMetadataSize=%zu",
+ __FUNCTION__, width, height, layerCount, format, usage, mUserMetadataSize);
auto status =
mClient.InvokeRemoteMethod<DetachedBufferRPC::Create>(width, height, layerCount, format,
usage, mUserMetadataSize);
if (!status) {
- ALOGE("BufferHubBuffer::BufferHubBuffer: Failed to create detached buffer: %s",
+ ALOGE("%s: Failed to create detached buffer: %s", __FUNCTION__,
status.GetErrorMessage().c_str());
mClient.Close(-status.error());
}
const int ret = ImportGraphicBuffer();
if (ret < 0) {
- ALOGE("BufferHubBuffer::BufferHubBuffer: Failed to import buffer: %s", strerror(-ret));
+ ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-ret));
mClient.Close(ret);
}
}
@@ -119,7 +118,7 @@
: mClient(std::move(mChannelHandle)) {
const int ret = ImportGraphicBuffer();
if (ret < 0) {
- ALOGE("BufferHubBuffer::BufferHubBuffer: Failed to import buffer: %s", strerror(-ret));
+ ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-ret));
mClient.Close(ret);
}
}
@@ -129,14 +128,14 @@
auto status = mClient.InvokeRemoteMethod<DetachedBufferRPC::Import>();
if (!status) {
- ALOGE("BufferHubBuffer::BufferHubBuffer: Failed to import GraphicBuffer: %s",
+ ALOGE("%s: Failed to import GraphicBuffer: %s", __FUNCTION__,
status.GetErrorMessage().c_str());
return -status.error();
}
BufferTraits<LocalHandle> bufferTraits = status.take();
if (bufferTraits.id() < 0) {
- ALOGE("BufferHubBuffer::BufferHubBuffer: Received an invalid id!");
+ ALOGE("%s: Received an invalid id!", __FUNCTION__);
return -EIO;
}
@@ -149,20 +148,19 @@
mMetadata = BufferHubMetadata::Import(std::move(metadataFd));
if (!mMetadata.IsValid()) {
- ALOGE("BufferHubBuffer::ImportGraphicBuffer: invalid metadata.");
+ ALOGE("%s: invalid metadata.", __FUNCTION__);
return -ENOMEM;
}
if (mMetadata.metadata_size() != bufferTraits.metadata_size()) {
- ALOGE("BufferHubBuffer::ImportGraphicBuffer: metadata buffer too small: "
- "%zu, expected: %" PRIu64 ".",
+ ALOGE("%s: metadata buffer too small: %zu, expected: %" PRIu64 ".", __FUNCTION__,
mMetadata.metadata_size(), bufferTraits.metadata_size());
return -ENOMEM;
}
size_t metadataSize = static_cast<size_t>(bufferTraits.metadata_size());
if (metadataSize < BufferHubDefs::kMetadataHeaderSize) {
- ALOGE("BufferHubBuffer::ImportGraphicBuffer: metadata too small: %zu", metadataSize);
+ ALOGE("%s: metadata too small: %zu", __FUNCTION__, metadataSize);
return -EINVAL;
}
@@ -191,22 +189,22 @@
mClientStateMask = bufferTraits.client_state_mask();
// TODO(b/112012161) Set up shared fences.
- ALOGD("BufferHubBuffer::ImportGraphicBuffer: id=%d, buffer_state=%" PRIx64 ".", id(),
+ ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, id(),
buffer_state_->load(std::memory_order_acquire));
return 0;
}
int BufferHubBuffer::Gain() {
- uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+ uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
if (IsClientGained(current_buffer_state, mClientStateMask)) {
- ALOGV("%s: Buffer is already gained by this client %" PRIx64 ".", __FUNCTION__,
+ ALOGV("%s: Buffer is already gained by this client %" PRIx32 ".", __FUNCTION__,
mClientStateMask);
return 0;
}
do {
if (AnyClientGained(current_buffer_state & (~mClientStateMask)) ||
AnyClientAcquired(current_buffer_state)) {
- ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+ ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
__FUNCTION__, mId, mClientStateMask, current_buffer_state);
return -EBUSY;
}
@@ -220,13 +218,13 @@
}
int BufferHubBuffer::Post() {
- uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
- uint64_t current_active_clients_bit_mask = 0ULL;
- uint64_t updated_buffer_state = 0ULL;
+ uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+ uint32_t current_active_clients_bit_mask = 0U;
+ uint32_t updated_buffer_state = 0U;
do {
if (!IsClientGained(current_buffer_state, mClientStateMask)) {
ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
- "mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+ "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
__FUNCTION__, mId, mClientStateMask, current_buffer_state);
return -EBUSY;
}
@@ -242,17 +240,17 @@
}
int BufferHubBuffer::Acquire() {
- uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+ uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
if (IsClientAcquired(current_buffer_state, mClientStateMask)) {
- ALOGV("%s: Buffer is already acquired by this client %" PRIx64 ".", __FUNCTION__,
+ ALOGV("%s: Buffer is already acquired by this client %" PRIx32 ".", __FUNCTION__,
mClientStateMask);
return 0;
}
- uint64_t updated_buffer_state = 0ULL;
+ uint32_t updated_buffer_state = 0U;
do {
if (!IsClientPosted(current_buffer_state, mClientStateMask)) {
ALOGE("%s: Cannot acquire a buffer that is not in posted state. buffer_id=%d "
- "mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+ "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
__FUNCTION__, mId, mClientStateMask, current_buffer_state);
return -EBUSY;
}
@@ -266,13 +264,13 @@
}
int BufferHubBuffer::Release() {
- uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+ uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
if (IsClientReleased(current_buffer_state, mClientStateMask)) {
- ALOGV("%s: Buffer is already released by this client %" PRIx64 ".", __FUNCTION__,
+ ALOGV("%s: Buffer is already released by this client %" PRIx32 ".", __FUNCTION__,
mClientStateMask);
return 0;
}
- uint64_t updated_buffer_state = 0ULL;
+ uint32_t updated_buffer_state = 0U;
do {
updated_buffer_state = current_buffer_state & (~mClientStateMask);
} while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
@@ -291,12 +289,12 @@
Status<LocalChannelHandle> BufferHubBuffer::Duplicate() {
ATRACE_CALL();
- ALOGD("BufferHubBuffer::Duplicate: id=%d.", mId);
+ ALOGD("%s: id=%d.", __FUNCTION__, mId);
auto statusOrHandle = mClient.InvokeRemoteMethod<DetachedBufferRPC::Duplicate>();
if (!statusOrHandle.ok()) {
- ALOGE("BufferHubBuffer::Duplicate: Failed to duplicate buffer (id=%d): %s.", mId,
+ ALOGE("%s: Failed to duplicate buffer (id=%d): %s.", __FUNCTION__, mId,
statusOrHandle.GetErrorMessage().c_str());
}
return statusOrHandle;
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 11e9b5c..90dd391 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -86,13 +86,13 @@
const native_handle_t* DuplicateHandle() { return mBufferHandle.DuplicateHandle(); }
// Returns the current value of MetadataHeader::buffer_state.
- uint64_t buffer_state() {
+ uint32_t buffer_state() {
return mMetadata.metadata_header()->buffer_state.load(std::memory_order_acquire);
}
// A state mask which is unique to a buffer hub client among all its siblings sharing the same
// concrete graphic buffer.
- uint64_t client_state_mask() const { return mClientStateMask; }
+ uint32_t client_state_mask() const { return mClientStateMask; }
size_t user_metadata_size() const { return mMetadata.user_metadata_size(); }
@@ -154,7 +154,7 @@
// Client state mask of this BufferHubBuffer object. It is unique amoung all
// clients/users of the buffer.
- uint64_t mClientStateMask = 0;
+ uint32_t mClientStateMask = 0U;
// Stores ground truth of the buffer.
AHardwareBuffer_Desc mBufferDesc;
@@ -166,9 +166,9 @@
// bufferhubd daemon and all buffer clients.
BufferHubMetadata mMetadata;
// Shortcuts to the atomics inside the header of mMetadata.
- std::atomic<uint64_t>* buffer_state_{nullptr};
- std::atomic<uint64_t>* fence_state_{nullptr};
- std::atomic<uint64_t>* active_clients_bit_mask_{nullptr};
+ std::atomic<uint32_t>* buffer_state_ = nullptr;
+ std::atomic<uint32_t>* fence_state_ = nullptr;
+ std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
// PDX backend.
BufferHubClient mClient;
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
index ef6668b..d259fef 100644
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -29,10 +29,10 @@
namespace BufferHubDefs {
-// Single buffer clients (up to 32) ownership signal.
-// 64-bit atomic unsigned int.
-// Each client takes 2 bits. The first bit locates in the first 32 bits of
-// buffer_state; the second bit locates in the last 32 bits of buffer_state.
+// Single buffer clients (up to 16) ownership signal.
+// 32-bit atomic unsigned int.
+// Each client takes 2 bits. The first bit locates in the first 16 bits of
+// buffer_state; the second bit locates in the last 16 bits of buffer_state.
// Client states:
// Gained state 11. Exclusive write state.
// Posted state 10.
@@ -42,88 +42,88 @@
// MSB LSB
// | |
// v v
-// [C31|...|C1|C0|C31| ... |C1|C0]
+// [C15|...|C1|C0|C15| ... |C1|C0]
// Maximum number of clients a buffer can have.
-static constexpr int kMaxNumberOfClients = 32;
+static constexpr int kMaxNumberOfClients = 16;
// Definition of bit masks.
// MSB LSB
// | kHighBitsMask | kLowbitsMask |
// v v v
-// [b63| ... |b32|b31| ... |b0]
+// [b31| ... |b16|b15| ... |b0]
-// The location of lower 32 bits in the 64-bit buffer state.
-static constexpr uint64_t kLowbitsMask = (1ULL << kMaxNumberOfClients) - 1ULL;
+// The location of lower 16 bits in the 32-bit buffer state.
+static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U;
-// The location of higher 32 bits in the 64-bit buffer state.
-static constexpr uint64_t kHighBitsMask = ~kLowbitsMask;
+// The location of higher 16 bits in the 32-bit buffer state.
+static constexpr uint32_t kHighBitsMask = ~kLowbitsMask;
// The client bit mask of the first client.
-static constexpr uint64_t kFirstClientBitMask = (1ULL << kMaxNumberOfClients) + 1ULL;
+static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
// Returns true if any of the client is in gained state.
-static inline bool AnyClientGained(uint64_t state) {
- uint64_t high_bits = state >> kMaxNumberOfClients;
- uint64_t low_bits = state & kLowbitsMask;
- return high_bits == low_bits && low_bits != 0ULL;
+static inline bool AnyClientGained(uint32_t state) {
+ uint32_t high_bits = state >> kMaxNumberOfClients;
+ uint32_t low_bits = state & kLowbitsMask;
+ return high_bits == low_bits && low_bits != 0U;
}
// Returns true if the input client is in gained state.
-static inline bool IsClientGained(uint64_t state, uint64_t client_bit_mask) {
+static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
return state == client_bit_mask;
}
// Returns true if any of the client is in posted state.
-static inline bool AnyClientPosted(uint64_t state) {
- uint64_t high_bits = state >> kMaxNumberOfClients;
- uint64_t low_bits = state & kLowbitsMask;
- uint64_t posted_or_acquired = high_bits ^ low_bits;
+static inline bool AnyClientPosted(uint32_t state) {
+ uint32_t high_bits = state >> kMaxNumberOfClients;
+ uint32_t low_bits = state & kLowbitsMask;
+ uint32_t posted_or_acquired = high_bits ^ low_bits;
return posted_or_acquired & high_bits;
}
// Returns true if the input client is in posted state.
-static inline bool IsClientPosted(uint64_t state, uint64_t client_bit_mask) {
- uint64_t client_bits = state & client_bit_mask;
- if (client_bits == 0ULL) return false;
- uint64_t low_bits = client_bits & kLowbitsMask;
- return low_bits == 0ULL;
+static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
+ uint32_t client_bits = state & client_bit_mask;
+ if (client_bits == 0U) return false;
+ uint32_t low_bits = client_bits & kLowbitsMask;
+ return low_bits == 0U;
}
// Return true if any of the client is in acquired state.
-static inline bool AnyClientAcquired(uint64_t state) {
- uint64_t high_bits = state >> kMaxNumberOfClients;
- uint64_t low_bits = state & kLowbitsMask;
- uint64_t posted_or_acquired = high_bits ^ low_bits;
+static inline bool AnyClientAcquired(uint32_t state) {
+ uint32_t high_bits = state >> kMaxNumberOfClients;
+ uint32_t low_bits = state & kLowbitsMask;
+ uint32_t posted_or_acquired = high_bits ^ low_bits;
return posted_or_acquired & low_bits;
}
// Return true if the input client is in acquired state.
-static inline bool IsClientAcquired(uint64_t state, uint64_t client_bit_mask) {
- uint64_t client_bits = state & client_bit_mask;
- if (client_bits == 0ULL) return false;
- uint64_t high_bits = client_bits & kHighBitsMask;
- return high_bits == 0ULL;
+static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
+ uint32_t client_bits = state & client_bit_mask;
+ if (client_bits == 0U) return false;
+ uint32_t high_bits = client_bits & kHighBitsMask;
+ return high_bits == 0U;
}
// Returns true if all clients are in released state.
-static inline bool IsBufferReleased(uint64_t state) {
- return state == 0ULL;
+static inline bool IsBufferReleased(uint32_t state) {
+ return state == 0U;
}
// Returns true if the input client is in released state.
-static inline bool IsClientReleased(uint64_t state, uint64_t client_bit_mask) {
- return (state & client_bit_mask) == 0ULL;
+static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
+ return (state & client_bit_mask) == 0U;
}
// Returns the next available buffer client's client_state_masks.
// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint64_t FindNextAvailableClientStateMask(uint64_t union_bits) {
- uint64_t low_union = union_bits & kLowbitsMask;
- if (low_union == kLowbitsMask) return 0ULL;
- uint64_t incremented = low_union + 1ULL;
- uint64_t difference = incremented ^ low_union;
- uint64_t new_low_bit = (difference + 1ULL) >> 1;
+static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
+ uint32_t low_union = union_bits & kLowbitsMask;
+ if (low_union == kLowbitsMask) return 0U;
+ uint32_t incremented = low_union + 1U;
+ uint32_t difference = incremented ^ low_union;
+ uint32_t new_low_bit = (difference + 1U) >> 1;
return new_low_bit + (new_low_bit << kMaxNumberOfClients);
}
@@ -135,15 +135,18 @@
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
// buffer_state.
- std::atomic<uint64_t> buffer_state;
+ std::atomic<uint32_t> buffer_state;
// Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32
// bits are there for easier manipulation, but the value should be ignored.
- std::atomic<uint64_t> fence_state;
+ std::atomic<uint32_t> fence_state;
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
// active_clients_bit_mask.
- std::atomic<uint64_t> active_clients_bit_mask;
+ std::atomic<uint32_t> active_clients_bit_mask;
+
+ // Explicit padding 4 bytes.
+ uint32_t padding;
// The index of the buffer queue where the buffer belongs to.
uint64_t queue_index;
@@ -152,7 +155,7 @@
DvrNativeBufferMetadata metadata;
};
-static_assert(sizeof(MetadataHeader) == 136, "Unexpected MetadataHeader size");
+static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
} // namespace BufferHubDefs
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index f616785..1b339a0 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -67,9 +67,9 @@
}
std::unique_ptr<BufferHubBuffer> b1;
- uint64_t b1ClientMask = 0ULL;
+ uint64_t b1ClientMask = 0U;
std::unique_ptr<BufferHubBuffer> b2;
- uint64_t b2ClientMask = 0ULL;
+ uint64_t b2ClientMask = 0U;
private:
// Creates b1 and b2 as the clients of the same buffer for testing.
@@ -79,13 +79,13 @@
void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() {
b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
b1ClientMask = b1->client_state_mask();
- ASSERT_NE(b1ClientMask, 0ULL);
+ ASSERT_NE(b1ClientMask, 0U);
auto statusOrHandle = b1->Duplicate();
ASSERT_TRUE(statusOrHandle);
LocalChannelHandle h2 = statusOrHandle.take();
b2 = BufferHubBuffer::Import(std::move(h2));
b2ClientMask = b2->client_state_mask();
- ASSERT_NE(b2ClientMask, 0ULL);
+ ASSERT_NE(b2ClientMask, 0U);
ASSERT_NE(b2ClientMask, b1ClientMask);
}
@@ -126,7 +126,7 @@
kUserMetadataSize);
int id1 = b1->id();
uint64_t bufferStateMask1 = b1->client_state_mask();
- EXPECT_NE(bufferStateMask1, 0ULL);
+ EXPECT_NE(bufferStateMask1, 0U);
EXPECT_TRUE(b1->IsValid());
EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
@@ -149,7 +149,7 @@
int id2 = b2->id();
uint64_t bufferStateMask2 = b2->client_state_mask();
- EXPECT_NE(bufferStateMask2, 0ULL);
+ EXPECT_NE(bufferStateMask2, 0U);
// These two buffer instances are based on the same physical buffer under the
// hood, so they should share the same id.
@@ -165,194 +165,6 @@
return;
}
-TEST_F(BufferHubBufferTest, AllocateAndFreeBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferHub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferHub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
- client = outClient;
- ret = outStatus;
- };
- EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
- EXPECT_EQ(BufferHubStatus::CLIENT_CLOSED, client->close());
-}
-
-TEST_F(BufferHubBufferTest, DuplicateFreedBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferHub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferHub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
- client = outClient;
- ret = outStatus;
- };
- EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- EXPECT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::CLIENT_CLOSED);
- EXPECT_EQ(token.getNativeHandle(), nullptr);
-}
-
-TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- ASSERT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(token.getNativeHandle(), nullptr);
- EXPECT_EQ(token->numInts, 1);
- EXPECT_EQ(token->numFds, 0);
-
- sp<IBufferClient> client2;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- ret = status;
- client2 = outClient;
- };
- ASSERT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- EXPECT_NE(nullptr, client2.get());
- // TODO(b/116681016): once BufferNode.id() is exposed via BufferHubBuffer, check origin.id =
- // improted.id here.
-}
-
-// nullptr must not crash the service
-TEST_F(BufferHubBufferTest, ImportNullToken) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- hidl_handle nullToken;
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->importBuffer(nullToken, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client.get());
-}
-
-// This test has a very little chance to fail (number of existing tokens / 2 ^ 32)
-TEST_F(BufferHubBufferTest, ImportInvalidToken) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- native_handle_t* tokenHandle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
- tokenHandle->data[0] = 0;
-
- hidl_handle invalidToken(tokenHandle);
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->importBuffer(invalidToken, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client.get());
-
- native_handle_delete(tokenHandle);
-}
-
-TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- ASSERT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(token.getNativeHandle(), nullptr);
- EXPECT_EQ(token->numInts, 1);
- EXPECT_EQ(token->numFds, 0);
-
- // Close the client. Now the token should be invalid.
- client->close();
-
- sp<IBufferClient> client2;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client2 = outClient;
- ret = status;
- };
- EXPECT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client2.get());
-}
-
TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) {
ASSERT_TRUE(IsBufferReleased(b1->buffer_state()));
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index c3fa77b..6cb6541 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -175,7 +175,7 @@
ASSERT_TRUE(p.get() != nullptr);
// It's ok to create up to kMaxConsumerCount consumer buffers.
- uint64_t client_state_masks = p->client_state_mask();
+ uint32_t client_state_masks = p->client_state_mask();
std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
for (size_t i = 0; i < kMaxConsumerCount; i++) {
cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
@@ -184,7 +184,7 @@
EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
client_state_masks |= cs[i]->client_state_mask();
}
- EXPECT_EQ(client_state_masks, ~0ULL);
+ EXPECT_EQ(client_state_masks, ~0U);
// The 64th creation will fail with out-of-memory error.
auto state = p->CreateConsumer();
@@ -373,7 +373,7 @@
std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
ASSERT_TRUE(p.get() != nullptr);
- uint64_t producer_state_mask = p->client_state_mask();
+ uint32_t producer_state_mask = p->client_state_mask();
std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
for (size_t i = 0; i < kMaxConsumerCount; ++i) {
@@ -719,7 +719,7 @@
std::unique_ptr<ConsumerBuffer> c1 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c1.get() != nullptr);
- const uint64_t client_state_mask1 = c1->client_state_mask();
+ const uint32_t client_state_mask1 = c1->client_state_mask();
EXPECT_EQ(0, p->GainAsync());
DvrNativeBufferMetadata meta;
@@ -739,7 +739,7 @@
std::unique_ptr<ConsumerBuffer> c2 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c2.get() != nullptr);
- const uint64_t client_state_mask2 = c2->client_state_mask();
+ const uint32_t client_state_mask2 = c2->client_state_mask();
EXPECT_NE(client_state_mask1, client_state_mask2);
EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
@@ -755,7 +755,7 @@
std::unique_ptr<ConsumerBuffer> c1 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c1.get() != nullptr);
- const uint64_t client_state_mask1 = c1->client_state_mask();
+ const uint32_t client_state_mask1 = c1->client_state_mask();
EXPECT_EQ(0, p->GainAsync());
DvrNativeBufferMetadata meta;
@@ -767,7 +767,7 @@
std::unique_ptr<ConsumerBuffer> c2 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c2.get() != nullptr);
- const uint64_t client_state_mask2 = c2->client_state_mask();
+ const uint32_t client_state_mask2 = c2->client_state_mask();
EXPECT_NE(client_state_mask1, client_state_mask2);
EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
LocalHandle invalid_fence;
@@ -781,7 +781,7 @@
std::unique_ptr<ConsumerBuffer> c3 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c3.get() != nullptr);
- const uint64_t client_state_mask3 = c3->client_state_mask();
+ const uint32_t client_state_mask3 = c3->client_state_mask();
EXPECT_NE(client_state_mask1, client_state_mask3);
EXPECT_NE(client_state_mask2, client_state_mask3);
EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
@@ -802,7 +802,7 @@
std::unique_ptr<ConsumerBuffer> c4 =
ConsumerBuffer::Import(p->CreateConsumer());
ASSERT_TRUE(c4.get() != nullptr);
- const uint64_t client_state_mask4 = c4->client_state_mask();
+ const uint32_t client_state_mask4 = c4->client_state_mask();
EXPECT_NE(client_state_mask3, client_state_mask4);
EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
@@ -952,7 +952,7 @@
int b1_id = b1->id();
EXPECT_TRUE(b1->IsValid());
EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
- EXPECT_NE(b1->client_state_mask(), 0ULL);
+ EXPECT_NE(b1->client_state_mask(), 0U);
auto status_or_handle = b1->Duplicate();
EXPECT_TRUE(status_or_handle);
@@ -970,7 +970,7 @@
ASSERT_TRUE(b2 != nullptr);
EXPECT_TRUE(b2->IsValid());
EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
- EXPECT_NE(b2->client_state_mask(), 0ULL);
+ EXPECT_NE(b2->client_state_mask(), 0U);
int b2_id = b2->id();
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
index 2dc427a..8497f3e 100644
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_base.cpp
@@ -124,16 +124,16 @@
// memory region will be preserved.
buffer_state_ = &metadata_header_->buffer_state;
ALOGD_IF(TRACE,
- "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx64 ".",
+ "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
id(), buffer_state_->load(std::memory_order_acquire));
fence_state_ = &metadata_header_->fence_state;
ALOGD_IF(TRACE,
- "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx64 ".", id(),
+ "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
fence_state_->load(std::memory_order_acquire));
active_clients_bit_mask_ = &metadata_header_->active_clients_bit_mask;
ALOGD_IF(
TRACE,
- "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx64
+ "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
".",
id(), active_clients_bit_mask_->load(std::memory_order_acquire));
@@ -171,7 +171,7 @@
// If ready fence is valid, we put that into the epoll set.
epoll_event event;
event.events = EPOLLIN;
- event.data.u64 = client_state_mask();
+ event.data.u32 = client_state_mask();
pending_fence_fd_ = new_fence.Duplicate();
if (epoll_ctl(shared_fence.Get(), EPOLL_CTL_ADD, pending_fence_fd_.Get(),
&event) < 0) {
diff --git a/libs/vr/libbufferhub/consumer_buffer.cpp b/libs/vr/libbufferhub/consumer_buffer.cpp
index 62fb5fd..b6ca64e 100644
--- a/libs/vr/libbufferhub/consumer_buffer.cpp
+++ b/libs/vr/libbufferhub/consumer_buffer.cpp
@@ -36,33 +36,33 @@
return -EINVAL;
// The buffer can be acquired iff the buffer state for this client is posted.
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (!BufferHubDefs::IsClientPosted(current_buffer_state,
client_state_mask())) {
ALOGE(
"%s: Failed to acquire the buffer. The buffer is not posted, id=%d "
- "state=%" PRIx64 " client_state_mask=%" PRIx64 ".",
+ "state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
__FUNCTION__, id(), current_buffer_state, client_state_mask());
return -EBUSY;
}
// Change the buffer state for this consumer from posted to acquired.
- uint64_t updated_buffer_state = current_buffer_state ^ client_state_mask();
+ uint32_t updated_buffer_state = current_buffer_state ^ client_state_mask();
while (!buffer_state_->compare_exchange_weak(
current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
std::memory_order_acquire)) {
ALOGD(
"%s Failed to acquire the buffer. Current buffer state was changed to "
- "%" PRIx64
+ "%" PRIx32
" when trying to acquire the buffer and modify the buffer state to "
- "%" PRIx64 ". About to try again if the buffer is still posted.",
+ "%" PRIx32 ". About to try again if the buffer is still posted.",
__FUNCTION__, current_buffer_state, updated_buffer_state);
if (!BufferHubDefs::IsClientPosted(current_buffer_state,
client_state_mask())) {
ALOGE(
"%s: Failed to acquire the buffer. The buffer is no longer posted, "
- "id=%d state=%" PRIx64 " client_state_mask=%" PRIx64 ".",
+ "id=%d state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
__FUNCTION__, id(), current_buffer_state, client_state_mask());
return -EBUSY;
}
@@ -81,7 +81,7 @@
out_meta->user_metadata_ptr = 0;
}
- uint64_t fence_state = fence_state_->load(std::memory_order_acquire);
+ uint32_t fence_state = fence_state_->load(std::memory_order_acquire);
// If there is an acquire fence from producer, we need to return it.
// The producer state bit mask is kFirstClientBitMask for now.
if (fence_state & BufferHubDefs::kFirstClientBitMask) {
@@ -142,21 +142,21 @@
// Set the buffer state of this client to released if it is not already in
// released state.
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (BufferHubDefs::IsClientReleased(current_buffer_state,
client_state_mask())) {
return 0;
}
- uint64_t updated_buffer_state = current_buffer_state & (~client_state_mask());
+ uint32_t updated_buffer_state = current_buffer_state & (~client_state_mask());
while (!buffer_state_->compare_exchange_weak(
current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
std::memory_order_acquire)) {
ALOGD(
"%s: Failed to release the buffer. Current buffer state was changed to "
- "%" PRIx64
+ "%" PRIx32
" when trying to release the buffer and modify the buffer state to "
- "%" PRIx64 ". About to try again.",
+ "%" PRIx32 ". About to try again.",
__FUNCTION__, current_buffer_state, updated_buffer_state);
// The failure of compare_exchange_weak updates current_buffer_state.
updated_buffer_state = current_buffer_state & (~client_state_mask());
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index 09feb73..440a59d 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -90,13 +90,13 @@
int cid() const { return cid_; }
// Returns the buffer buffer state.
- uint64_t buffer_state() {
+ uint32_t buffer_state() {
return buffer_state_->load(std::memory_order_acquire);
};
// A state mask which is unique to a buffer hub client among all its siblings
// sharing the same concrete graphic buffer.
- uint64_t client_state_mask() const { return client_state_mask_; }
+ uint32_t client_state_mask() const { return client_state_mask_; }
// The following methods return settings of the first buffer. Currently,
// it is only possible to create multi-buffer BufferHubBases with the same
@@ -132,11 +132,11 @@
// IonBuffer that is shared between bufferhubd, producer, and consumers.
size_t metadata_buf_size_{0};
size_t user_metadata_size_{0};
- BufferHubDefs::MetadataHeader* metadata_header_{nullptr};
- void* user_metadata_ptr_{nullptr};
- std::atomic<uint64_t>* buffer_state_{nullptr};
- std::atomic<uint64_t>* fence_state_{nullptr};
- std::atomic<uint64_t>* active_clients_bit_mask_{nullptr};
+ BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
+ void* user_metadata_ptr_ = nullptr;
+ std::atomic<uint32_t>* buffer_state_ = nullptr;
+ std::atomic<uint32_t>* fence_state_ = nullptr;
+ std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
LocalHandle shared_acquire_fence_;
LocalHandle shared_release_fence_;
@@ -159,7 +159,7 @@
// Client bit mask which indicates the locations of this client object in the
// buffer_state_.
- uint64_t client_state_mask_{0ULL};
+ uint32_t client_state_mask_{0U};
IonBuffer buffer_;
IonBuffer metadata_buffer_;
};
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
index 2de36f2..f2c40fe 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
@@ -22,46 +22,46 @@
// See more details in libs/ui/include/ui/BufferHubDefs.h
static constexpr int kMaxNumberOfClients =
android::BufferHubDefs::kMaxNumberOfClients;
-static constexpr uint64_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask;
-static constexpr uint64_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask;
-static constexpr uint64_t kFirstClientBitMask =
+static constexpr uint32_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask;
+static constexpr uint32_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask;
+static constexpr uint32_t kFirstClientBitMask =
android::BufferHubDefs::kFirstClientBitMask;
-static inline bool AnyClientGained(uint64_t state) {
+static inline bool AnyClientGained(uint32_t state) {
return android::BufferHubDefs::AnyClientGained(state);
}
-static inline bool IsClientGained(uint64_t state, uint64_t client_bit_mask) {
+static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
return android::BufferHubDefs::IsClientGained(state, client_bit_mask);
}
-static inline bool AnyClientPosted(uint64_t state) {
+static inline bool AnyClientPosted(uint32_t state) {
return android::BufferHubDefs::AnyClientPosted(state);
}
-static inline bool IsClientPosted(uint64_t state, uint64_t client_bit_mask) {
+static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
return android::BufferHubDefs::IsClientPosted(state, client_bit_mask);
}
-static inline bool AnyClientAcquired(uint64_t state) {
+static inline bool AnyClientAcquired(uint32_t state) {
return android::BufferHubDefs::AnyClientAcquired(state);
}
-static inline bool IsClientAcquired(uint64_t state, uint64_t client_bit_mask) {
+static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
return android::BufferHubDefs::IsClientAcquired(state, client_bit_mask);
}
-static inline bool IsBufferReleased(uint64_t state) {
+static inline bool IsBufferReleased(uint32_t state) {
return android::BufferHubDefs::IsBufferReleased(state);
}
-static inline bool IsClientReleased(uint64_t state, uint64_t client_bit_mask) {
+static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
return android::BufferHubDefs::IsClientReleased(state, client_bit_mask);
}
// Returns the next available buffer client's client_state_masks.
// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint64_t FindNextAvailableClientStateMask(uint64_t union_bits) {
+static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
return android::BufferHubDefs::FindNextAvailableClientStateMask(union_bits);
}
@@ -77,7 +77,7 @@
BufferTraits() = default;
BufferTraits(const native_handle_t* buffer_handle,
const FileHandleType& metadata_handle, int id,
- uint64_t client_state_mask, uint64_t metadata_size,
+ uint32_t client_state_mask, uint64_t metadata_size,
uint32_t width, uint32_t height, uint32_t layer_count,
uint32_t format, uint64_t usage, uint32_t stride,
const FileHandleType& acquire_fence_fd,
@@ -107,7 +107,7 @@
// same buffer channel has uniqued state bit among its siblings. For a
// producer buffer the bit must be kFirstClientBitMask; for a consumer the bit
// must be one of the kConsumerStateMask.
- uint64_t client_state_mask() const { return client_state_mask_; }
+ uint32_t client_state_mask() const { return client_state_mask_; }
uint64_t metadata_size() const { return metadata_size_; }
uint32_t width() { return width_; }
@@ -131,7 +131,7 @@
private:
// BufferHub specific traits.
int id_ = -1;
- uint64_t client_state_mask_;
+ uint32_t client_state_mask_;
uint64_t metadata_size_;
// Traits for a GraphicBuffer.
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index 5ff4e00..f1cd0b4 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -99,7 +99,7 @@
public:
BufferDescription() = default;
BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
- int buffer_cid, uint64_t client_state_mask,
+ int buffer_cid, uint32_t client_state_mask,
const FileHandleType& acquire_fence_fd,
const FileHandleType& release_fence_fd)
: id_(id),
@@ -123,7 +123,7 @@
// State mask of the buffer client. Each BufferHub client backed by the
// same buffer channel has uniqued state bit among its siblings.
- uint64_t client_state_mask() const { return client_state_mask_; }
+ uint32_t client_state_mask() const { return client_state_mask_; }
FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
@@ -133,7 +133,7 @@
private:
int id_{-1};
int buffer_cid_{-1};
- uint64_t client_state_mask_{0};
+ uint32_t client_state_mask_{0U};
// Two IonBuffers: one for the graphic buffer and one for metadata.
NativeBufferHandle<FileHandleType> buffer_;
NativeBufferHandle<FileHandleType> metadata_;
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index cd92b62..5274bf2 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -80,20 +80,20 @@
return error;
// The buffer can be posted iff the buffer state for this client is gained.
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (!BufferHubDefs::IsClientGained(current_buffer_state,
client_state_mask())) {
- ALOGE("%s: not gained, id=%d state=%" PRIx64 ".", __FUNCTION__, id(),
+ ALOGE("%s: not gained, id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
current_buffer_state);
return -EBUSY;
}
// Set the producer client buffer state to released, other clients' buffer
// state to posted.
- uint64_t current_active_clients_bit_mask =
+ uint32_t current_active_clients_bit_mask =
active_clients_bit_mask_->load(std::memory_order_acquire);
- uint64_t updated_buffer_state = current_active_clients_bit_mask &
+ uint32_t updated_buffer_state = current_active_clients_bit_mask &
(~client_state_mask()) &
BufferHubDefs::kHighBitsMask;
while (!buffer_state_->compare_exchange_weak(
@@ -101,16 +101,16 @@
std::memory_order_acquire)) {
ALOGD(
"%s: Failed to post the buffer. Current buffer state was changed to "
- "%" PRIx64
+ "%" PRIx32
" when trying to post the buffer and modify the buffer state to "
- "%" PRIx64
+ "%" PRIx32
". About to try again if the buffer is still gained by this client.",
__FUNCTION__, current_buffer_state, updated_buffer_state);
if (!BufferHubDefs::IsClientGained(current_buffer_state,
client_state_mask())) {
ALOGE(
"%s: Failed to post the buffer. The buffer is no longer gained, "
- "id=%d state=%" PRIx64 ".",
+ "id=%d state=%" PRIx32 ".",
__FUNCTION__, id(), current_buffer_state);
return -EBUSY;
}
@@ -164,9 +164,9 @@
if (!out_meta)
return -EINVAL;
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
- ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx64 ".", __FUNCTION__, id(),
+ ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx32 ".", __FUNCTION__, id(),
current_buffer_state);
if (BufferHubDefs::IsClientGained(current_buffer_state,
@@ -178,20 +178,20 @@
BufferHubDefs::AnyClientGained(current_buffer_state) ||
(BufferHubDefs::AnyClientPosted(current_buffer_state) &&
!gain_posted_buffer)) {
- ALOGE("%s: not released id=%d state=%" PRIx64 ".", __FUNCTION__, id(),
+ ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
current_buffer_state);
return -EBUSY;
}
// Change the buffer state to gained state.
- uint64_t updated_buffer_state = client_state_mask();
+ uint32_t updated_buffer_state = client_state_mask();
while (!buffer_state_->compare_exchange_weak(
current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
std::memory_order_acquire)) {
ALOGD(
"%s: Failed to gain the buffer. Current buffer state was changed to "
- "%" PRIx64
+ "%" PRIx32
" when trying to gain the buffer and modify the buffer state to "
- "%" PRIx64
+ "%" PRIx32
". About to try again if the buffer is still not read by other "
"clients.",
__FUNCTION__, current_buffer_state, updated_buffer_state);
@@ -202,7 +202,7 @@
!gain_posted_buffer)) {
ALOGE(
"%s: Failed to gain the buffer. The buffer is no longer released. "
- "id=%d state=%" PRIx64 ".",
+ "id=%d state=%" PRIx32 ".",
__FUNCTION__, id(), current_buffer_state);
return -EBUSY;
}
@@ -221,8 +221,8 @@
out_meta->user_metadata_ptr = 0;
}
- uint64_t current_fence_state = fence_state_->load(std::memory_order_acquire);
- uint64_t current_active_clients_bit_mask =
+ uint32_t current_fence_state = fence_state_->load(std::memory_order_acquire);
+ uint32_t current_active_clients_bit_mask =
active_clients_bit_mask_->load(std::memory_order_acquire);
// If there are release fence(s) from consumer(s), we need to return it to the
// consumer(s).
@@ -289,11 +289,11 @@
// TODO(b/112338294) Keep here for reference. Remove it after new logic is
// written.
- /* uint64_t buffer_state = buffer_state_->load(std::memory_order_acquire);
+ /* uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
if (!BufferHubDefs::IsClientGained(
buffer_state, BufferHubDefs::kFirstClientStateMask)) {
// Can only detach a ProducerBuffer when it's in gained state.
- ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx64
+ ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx32
") is not in gained state.",
id(), buffer_state);
return {};
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
index 6e303a5..2f14f7c 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
@@ -28,7 +28,7 @@
return -EALREADY;
}
- fd_.reset(epoll_create(64));
+ fd_.reset(epoll_create1(EPOLL_CLOEXEC));
if (fd_.get() < 0)
return -errno;
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index a204f62..e383bb2 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -466,11 +466,11 @@
// Only applicable for metadata retrieved from GainAsync. This indicates which
// consumer has pending fence that producer should epoll on.
- uint64_t release_fence_mask;
+ uint32_t release_fence_mask;
// Reserved bytes for so that the struct is forward compatible and padding to
// 104 bytes so the size is a multiple of 8.
- int32_t reserved[8];
+ int32_t reserved[9];
};
#ifdef __cplusplus
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 2d5f004..df06097 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -62,7 +62,7 @@
buffer_removed_count_);
}
- DvrWriteBufferQueue* write_queue_{nullptr};
+ DvrWriteBufferQueue* write_queue_ = nullptr;
int buffer_available_count_{0};
int buffer_removed_count_{0};
};
diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
index 962c745..1cf5f17 100644
--- a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
+++ b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
@@ -11,7 +11,7 @@
namespace dvr {
EpollEventDispatcher::EpollEventDispatcher() {
- epoll_fd_.Reset(epoll_create(64));
+ epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
if (!epoll_fd_) {
ALOGE("Failed to create epoll fd: %s", strerror(errno));
return;
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 50e30c2..f5cf3dc 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -554,33 +554,17 @@
property_get("ro.product.manufacturer", manufacturer, "UNSET");
property_get("ro.product.model", model, "UNSET");
- // TODO: Replace this with the new function name once the version-1 API is removed:
- fpANGLEGetUtilityAPI ANGLEGetUtilityAPI =
- (fpANGLEGetUtilityAPI)dlsym(so, "ANGLEGetUtilityAPI");
+ fpANGLEGetFeatureSupportUtilAPIVersion ANGLEGetFeatureSupportUtilAPIVersion =
+ (fpANGLEGetFeatureSupportUtilAPIVersion)dlsym(so, "ANGLEGetFeatureSupportUtilAPIVersion");
- if (ANGLEGetUtilityAPI) {
+ if (ANGLEGetFeatureSupportUtilAPIVersion) {
// Negotiate the interface version by requesting most recent known to the platform
unsigned int versionToUse = 2;
- // TODO: Replace this with the new function name once the version-1 API is removed:
- if ((ANGLEGetUtilityAPI)(&versionToUse)) {
+ if ((ANGLEGetFeatureSupportUtilAPIVersion)(&versionToUse)) {
// Add and remove versions below as needed
switch(versionToUse) {
- case 1: {
- ALOGV("Using version 1 of ANGLE feature-support library");
- fpAndroidUseANGLEForApplication AndroidUseANGLEForApplication =
- (fpAndroidUseANGLEForApplication)dlsym(so, "AndroidUseANGLEForApplication");
-
- if (AndroidUseANGLEForApplication) {
- use_angle = (AndroidUseANGLEForApplication)(rules_fd, rules_offset,
- rules_length, app_name_str.c_str(),
- manufacturer, model);
- } else {
- ALOGW("Cannot find AndroidUseANGLEForApplication in ANGLE feature-support library");
- }
- }
- break;
case 2: {
ALOGV("Using version 2 of ANGLE feature-support library");
void* rules_handle = nullptr;
@@ -647,7 +631,7 @@
ALOGW("Cannot use ANGLE feature-support library, it is older than supported by EGL, requested version %u", versionToUse);
}
} else {
- ALOGW("Cannot find ANGLEGetUtilityAPI function");
+ ALOGW("Cannot find ANGLEGetFeatureSupportUtilAPIVersion function");
}
ALOGV("Close temporarily-loaded ANGLE opt-in/out logic");
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 4bad829..cc87e15 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -14,10 +14,10 @@
// Using placement new here to reuse shared memory instead of new allocation
// Initialize the atomic variables to zero.
BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
- buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0);
- fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0);
+ buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint32_t>(0);
+ fence_state_ = new (&metadata_header->fence_state) std::atomic<uint32_t>(0);
active_clients_bit_mask_ =
- new (&metadata_header->active_clients_bit_mask) std::atomic<uint64_t>(0);
+ new (&metadata_header->active_clients_bit_mask) std::atomic<uint32_t>(0);
}
// Allocates a new BufferNode.
@@ -74,22 +74,22 @@
}
}
-uint64_t BufferNode::GetActiveClientsBitMask() const {
+uint32_t BufferNode::GetActiveClientsBitMask() const {
return active_clients_bit_mask_->load(std::memory_order_acquire);
}
-uint64_t BufferNode::AddNewActiveClientsBitToMask() {
- uint64_t current_active_clients_bit_mask = GetActiveClientsBitMask();
- uint64_t client_state_mask = 0ULL;
- uint64_t updated_active_clients_bit_mask = 0ULL;
+uint32_t BufferNode::AddNewActiveClientsBitToMask() {
+ uint32_t current_active_clients_bit_mask = GetActiveClientsBitMask();
+ uint32_t client_state_mask = 0U;
+ uint32_t updated_active_clients_bit_mask = 0U;
do {
client_state_mask =
BufferHubDefs::FindNextAvailableClientStateMask(current_active_clients_bit_mask);
- if (client_state_mask == 0ULL) {
+ if (client_state_mask == 0U) {
ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__,
BufferHubDefs::kMaxNumberOfClients);
errno = E2BIG;
- return 0ULL;
+ return 0U;
}
updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask;
} while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask,
@@ -99,7 +99,7 @@
return client_state_mask;
}
-void BufferNode::RemoveClientsBitFromMask(const uint64_t& value) {
+void BufferNode::RemoveClientsBitFromMask(const uint32_t& value) {
active_clients_bit_mask_->fetch_and(~value);
}
diff --git a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
index c5b2cde..b51fcda 100644
--- a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
+++ b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
@@ -32,7 +32,7 @@
class BufferHubIdGenerator {
public:
// 0 is considered invalid
- static constexpr uint32_t kInvalidId = 0UL;
+ static constexpr uint32_t kInvalidId = 0U;
// Get the singleton instance of this class
static BufferHubIdGenerator& getInstance();
diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h
index 02bb5af..cf56c33 100644
--- a/services/bufferhub/include/bufferhub/BufferNode.h
+++ b/services/bufferhub/include/bufferhub/BufferNode.h
@@ -38,19 +38,19 @@
// Gets the current value of active_clients_bit_mask in metadata_ with
// std::memory_order_acquire, so that all previous releases of
// active_clients_bit_mask from all threads will be returned here.
- uint64_t GetActiveClientsBitMask() const;
+ uint32_t GetActiveClientsBitMask() const;
// Find and add a new client_state_mask to active_clients_bit_mask in
// metadata_.
// Return the new client_state_mask that is added to active_clients_bit_mask.
- // Return 0ULL if there are already 32 bp clients of the buffer.
- uint64_t AddNewActiveClientsBitToMask();
+ // Return 0U if there are already 16 clients of the buffer.
+ uint32_t AddNewActiveClientsBitToMask();
// Removes the value from active_clients_bit_mask in metadata_ with
// std::memory_order_release, so that the change will be visible to any
// acquire of active_clients_bit_mask_ in any threads after the succeed of
// this operation.
- void RemoveClientsBitFromMask(const uint64_t& value);
+ void RemoveClientsBitFromMask(const uint32_t& value);
private:
// Helper method for constructors to initialize atomic metadata header
@@ -75,14 +75,14 @@
// buffer_state_ tracks the state of the buffer. Buffer can be in one of these
// four states: gained, posted, acquired, released.
- std::atomic<uint64_t>* buffer_state_ = nullptr;
+ std::atomic<uint32_t>* buffer_state_ = nullptr;
// TODO(b/112012161): add comments to fence_state_.
- std::atomic<uint64_t>* fence_state_ = nullptr;
+ std::atomic<uint32_t>* fence_state_ = nullptr;
// active_clients_bit_mask_ tracks all the bp clients of the buffer. It is the
// union of all client_state_mask of all bp clients.
- std::atomic<uint64_t>* active_clients_bit_mask_ = nullptr;
+ std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
};
} // namespace implementation
diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp
index 8555eb7..dbf10e8 100644
--- a/services/bufferhub/tests/BufferNode_test.cpp
+++ b/services/bufferhub/tests/BufferNode_test.cpp
@@ -56,21 +56,21 @@
}
TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_twoNewClients) {
- uint64_t new_client_state_mask_1 = buffer_node->AddNewActiveClientsBitToMask();
+ uint32_t new_client_state_mask_1 = buffer_node->AddNewActiveClientsBitToMask();
EXPECT_EQ(buffer_node->GetActiveClientsBitMask(), new_client_state_mask_1);
// Request and add a new client_state_mask again.
// Active clients bit mask should be the union of the two new
// client_state_masks.
- uint64_t new_client_state_mask_2 = buffer_node->AddNewActiveClientsBitToMask();
+ uint32_t new_client_state_mask_2 = buffer_node->AddNewActiveClientsBitToMask();
EXPECT_EQ(buffer_node->GetActiveClientsBitMask(),
new_client_state_mask_1 | new_client_state_mask_2);
}
TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_32NewClients) {
- uint64_t new_client_state_mask = 0ULL;
- uint64_t current_mask = 0ULL;
- uint64_t expected_mask = 0ULL;
+ uint32_t new_client_state_mask = 0U;
+ uint32_t current_mask = 0U;
+ uint32_t expected_mask = 0U;
for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) {
new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
@@ -83,14 +83,14 @@
// Method should fail upon requesting for more than maximum allowable clients.
new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
- EXPECT_EQ(new_client_state_mask, 0ULL);
+ EXPECT_EQ(new_client_state_mask, 0U);
EXPECT_EQ(errno, E2BIG);
}
TEST_F(BufferNodeTest, TestRemoveActiveClientsBitFromMask) {
buffer_node->AddNewActiveClientsBitToMask();
- uint64_t current_mask = buffer_node->GetActiveClientsBitMask();
- uint64_t new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
+ uint32_t current_mask = buffer_node->GetActiveClientsBitMask();
+ uint32_t new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
EXPECT_NE(buffer_node->GetActiveClientsBitMask(), current_mask);
buffer_node->RemoveClientsBitFromMask(new_client_state_mask);
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 31057f6..5709e1e 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -203,7 +203,7 @@
mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
- mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+ mEpollFd = epoll_create1(EPOLL_CLOEXEC);
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
mINotifyFd = inotify_init();
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 7e00f42..5d0b894 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2642,7 +2642,6 @@
mOrientation = internalViewport->orientation;
}
}
- getPolicy()->updatePointerDisplay();
bumpGeneration();
}
}
@@ -2788,7 +2787,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
- displayId = mPointerController->getDisplayId();
+ displayId = ADISPLAY_ID_DEFAULT;
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
@@ -3609,9 +3608,6 @@
(mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
if (mPointerController == nullptr) {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
- getPolicy()->updatePointerDisplay();
- } else if (viewportChanged) {
- getPolicy()->updatePointerDisplay();
}
} else {
mPointerController.clear();
@@ -5399,9 +5395,9 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- int32_t displayId = mPointerController->getDisplayId();
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, displayId, mSource,
- mViewport.displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
/* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, mPointerGesture.downTime);
@@ -6307,7 +6303,6 @@
void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
bool down, bool hovering) {
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t displayId = mViewport.displayId;
if (mPointerController != nullptr) {
if (down || hovering) {
@@ -6318,20 +6313,19 @@
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
}
- displayId = mPointerController->getDisplayId();
}
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
// Send up.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
- /* deviceTimestamp */ 0,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
+ AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
+ /* deviceTimestamp */ 0,
+ 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+ mOrientedXPrecision, mOrientedYPrecision,
+ mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
@@ -6339,8 +6333,8 @@
mPointerSimple.hovering = false;
// Send hover exit.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -6355,8 +6349,8 @@
mPointerSimple.downTime = when;
// Send down.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6366,8 +6360,8 @@
}
// Send move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6381,8 +6375,8 @@
mPointerSimple.hovering = true;
// Send hover enter.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
@@ -6393,8 +6387,8 @@
}
// Send hover move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
@@ -6416,8 +6410,8 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &pointerCoords,
@@ -6479,10 +6473,9 @@
ALOG_ASSERT(false);
}
}
- int32_t displayId = mPointerController != nullptr ?
- mPointerController->getDisplayId() : mViewport.displayId;
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- source, displayId, policyFlags,
+
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ source, mViewport.displayId, policyFlags,
action, actionButton, flags, metaState, buttonState, edgeFlags,
deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
xPrecision, yPrecision, downTime);
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 5a78df7..fe1c50b 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -342,9 +342,6 @@
/* Gets the affine calibration associated with the specified device. */
virtual TouchAffineTransformation getTouchAffineTransformation(
const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
-
- /* Update the pointer controller associated with the specified display. */
- virtual void updatePointerDisplay() = 0;
};
} // namespace android
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index e60b3f4..e94dd94 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -58,9 +58,6 @@
/* Gets the absolute location of the pointer. */
virtual void getPosition(float* outX, float* outY) const = 0;
- /* Gets the id of the display where the pointer should be shown. */
- virtual int32_t getDisplayId() const = 0;
-
enum Transition {
// Fade/unfade immediately.
TRANSITION_IMMEDIATE,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 855247f..167a624 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -57,7 +57,6 @@
float mMinX, mMinY, mMaxX, mMaxY;
float mX, mY;
int32_t mButtonState;
- int32_t mDisplayId;
protected:
virtual ~FakePointerController() { }
@@ -65,7 +64,7 @@
public:
FakePointerController() :
mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
- mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
+ mButtonState(0) {
}
void setBounds(float minX, float minY, float maxX, float maxY) {
@@ -76,10 +75,6 @@
mMaxY = maxY;
}
- void setDisplayId(int32_t displayId) {
- mDisplayId = displayId;
- }
-
virtual void setPosition(float x, float y) {
mX = x;
mY = y;
@@ -98,10 +93,6 @@
*outY = mY;
}
- virtual int32_t getDisplayId() const {
- return mDisplayId;
- }
-
private:
virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
*outMinX = mMinX;
@@ -271,9 +262,6 @@
virtual std::string getDeviceAlias(const InputDeviceIdentifier&) {
return "";
}
-
- virtual void updatePointerDisplay() {
- }
};
@@ -3177,30 +3165,6 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
}
-TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
- CursorInputMapper* mapper = new CursorInputMapper(mDevice);
- addMapperAndConfigure(mapper);
-
- // Setup PointerController for second display.
- constexpr int32_t SECOND_DISPLAY_ID = 1;
- mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
- mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
- mFakePointerController->setDisplayId(SECOND_DISPLAY_ID);
-
- NotifyMotionArgs args;
- process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
- ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
- ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
- ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId);
-}
-
// --- TouchInputMapperTest ---
@@ -4699,6 +4663,7 @@
toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
}
+
// --- MultiTouchInputMapperTest ---
class MultiTouchInputMapperTest : public TouchInputMapperTest {
@@ -6319,30 +6284,4 @@
ASSERT_EQ(DISPLAY_ID, args.displayId);
}
-TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
- // Setup PointerController for second display.
- sp<FakePointerController> fakePointerController = new FakePointerController();
- fakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
- fakePointerController->setPosition(100, 200);
- fakePointerController->setButtonState(0);
- fakePointerController->setDisplayId(SECONDARY_DISPLAY_ID);
- mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
-
- MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
- prepareDisplay(DISPLAY_ORIENTATION_0);
- prepareAxes(POSITION);
- addMapperAndConfigure(mapper);
-
- // Check source is mouse that would obtain the PointerController.
- ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
-
- NotifyMotionArgs motionArgs;
- processPosition(mapper, 100, 100);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
- ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
-}
-
} // namespace android
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index f87fcdc..33a2747 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -41,6 +41,7 @@
"liblog",
"libbinder",
"libsensor",
+ "libsensorprivacy",
"libcrypto",
"libbase",
"libhidlbase",
@@ -53,8 +54,8 @@
static_libs: ["android.hardware.sensors@1.0-convert"],
- // our public headers depend on libsensor
- export_shared_lib_headers: ["libsensor"],
+ // our public headers depend on libsensor and libsensorprivacy
+ export_shared_lib_headers: ["libsensor", "libsensorprivacy"],
}
cc_binary {
@@ -64,6 +65,7 @@
shared_libs: [
"libsensorservice",
+ "libsensorprivacy",
"libbinder",
"libutils",
],
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 776efab..b66cbcf 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -279,7 +279,7 @@
}
} else {
// Regular sensor event, just copy it to the scratch buffer.
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
scratch[count++] = buffer[i];
}
}
@@ -290,7 +290,7 @@
buffer[i].meta_data.sensor == sensor_handle)));
}
} else {
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
scratch = const_cast<sensors_event_t *>(buffer);
count = numEvents;
} else {
@@ -321,7 +321,7 @@
}
int index_wake_up_event = -1;
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
if (index_wake_up_event >= 0) {
scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
@@ -375,6 +375,10 @@
mHasSensorAccess = hasAccess;
}
+bool SensorService::SensorEventConnection::hasSensorAccess() {
+ return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
+}
+
void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
int count) {
sensors_event_t *eventCache_new;
@@ -491,7 +495,7 @@
for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
int index_wake_up_event = -1;
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
index_wake_up_event =
findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
if (index_wake_up_event >= 0) {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 061809f..7077880 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -130,6 +130,10 @@
void updateLooperRegistration(const sp<Looper>& looper); void
updateLooperRegistrationLocked(const sp<Looper>& looper);
+ // Returns whether sensor access is available based on both the uid being active and sensor
+ // privacy not being enabled.
+ bool hasSensorAccess();
+
sp<SensorService> const mService;
sp<BitTube> mChannel;
uid_t mUid;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 85450f8..9a37ff1 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -29,6 +29,7 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <sensor/SensorEventQueue.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
#include <utils/SystemClock.h>
#include "BatteryService.h"
@@ -88,6 +89,7 @@
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
mWakeLockAcquired(false) {
mUidPolicy = new UidPolicy(this);
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
}
bool SensorService::initializeHmacKey() {
@@ -286,6 +288,9 @@
// Start watching UID changes to apply policy.
mUidPolicy->registerSelf();
+
+ // Start watching sensor privacy changes
+ mSensorPrivacyPolicy->registerSelf();
}
}
}
@@ -338,6 +343,7 @@
delete entry.second;
}
mUidPolicy->unregisterSelf();
+ mSensorPrivacyPolicy->unregisterSelf();
}
status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -364,35 +370,16 @@
}
mCurrentOperatingMode = RESTRICTED;
- // temporarily stop all sensor direct report
- for (auto &i : mDirectConnections) {
- sp<SensorDirectConnection> connection(i.promote());
- if (connection != nullptr) {
- connection->stopAll(true /* backupRecord */);
- }
- }
-
- dev.disableAllSensors();
- // Clear all pending flush connections for all active sensors. If one of the active
- // connections has called flush() and the underlying sensor has been disabled before a
- // flush complete event is returned, we need to remove the connection from this queue.
- for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
- mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
- }
+ // temporarily stop all sensor direct report and disable sensors
+ disableAllSensorsLocked();
mWhiteListedPackage.setTo(String8(args[1]));
return status_t(NO_ERROR);
} else if (args.size() == 1 && args[0] == String16("enable")) {
// If currently in restricted mode, reset back to NORMAL mode else ignore.
if (mCurrentOperatingMode == RESTRICTED) {
mCurrentOperatingMode = NORMAL;
- dev.enableAllSensors();
- // recover all sensor direct report
- for (auto &i : mDirectConnections) {
- sp<SensorDirectConnection> connection(i.promote());
- if (connection != nullptr) {
- connection->recoverAll();
- }
- }
+ // enable sensors and recover all sensor direct report
+ enableAllSensorsLocked();
}
if (mCurrentOperatingMode == DATA_INJECTION) {
resetToNormalModeLocked();
@@ -477,6 +464,8 @@
case DATA_INJECTION:
result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
}
+ result.appendFormat("Sensor Privacy: %s\n",
+ mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
result.appendFormat("%zd active connections\n", mActiveConnections.size());
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
@@ -519,6 +508,52 @@
return NO_ERROR;
}
+void SensorService::disableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ disableAllSensorsLocked();
+}
+
+void SensorService::disableAllSensorsLocked() {
+ SensorDevice& dev(SensorDevice::getInstance());
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->stopAll(true /* backupRecord */);
+ }
+ }
+ dev.disableAllSensors();
+ // Clear all pending flush connections for all active sensors. If one of the active
+ // connections has called flush() and the underlying sensor has been disabled before a
+ // flush complete event is returned, we need to remove the connection from this queue.
+ for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
+ mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
+ }
+}
+
+void SensorService::enableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ enableAllSensorsLocked();
+}
+
+void SensorService::enableAllSensorsLocked() {
+ // sensors should only be enabled if the operating state is not restricted and sensor
+ // privacy is not enabled.
+ if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ ALOGW("Sensors cannot be enabled: mCurrentOperatingMode = %d, sensor privacy = %s",
+ mCurrentOperatingMode,
+ mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
+ return;
+ }
+ SensorDevice& dev(SensorDevice::getInstance());
+ dev.enableAllSensors();
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->recoverAll();
+ }
+ }
+}
+
// NOTE: This is a remote API - make sure all args are validated
status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) {
if (!checkCallingPermission(sManageSensorsPermission, nullptr, nullptr)) {
@@ -1076,6 +1111,12 @@
const native_handle *resource) {
Mutex::Autolock _l(mLock);
+ // No new direct connections are allowed when sensor privacy is enabled
+ if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ ALOGE("Cannot create new direct connections when sensor privacy is enabled");
+ return nullptr;
+ }
+
struct sensors_direct_mem_t mem = {
.type = type,
.format = format,
@@ -1753,4 +1794,31 @@
return mActiveUids.find(uid) != mActiveUids.end();
}
+void SensorService::SensorPrivacyPolicy::registerSelf() {
+ SensorPrivacyManager spm;
+ mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+ spm.addSensorPrivacyListener(this);
+}
+
+void SensorService::SensorPrivacyPolicy::unregisterSelf() {
+ SensorPrivacyManager spm;
+ spm.removeSensorPrivacyListener(this);
+}
+
+bool SensorService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+ return mSensorPrivacyEnabled;
+}
+
+binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+ mSensorPrivacyEnabled = enabled;
+ sp<SensorService> service = mService.promote();
+ if (service != nullptr) {
+ if (enabled) {
+ service->disableAllSensors();
+ } else {
+ service->enableAllSensors();
+ }
+ }
+ return binder::Status::ok();
+}
}; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 24b0dd7..136ee27 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -26,6 +26,7 @@
#include <sensor/ISensorServer.h>
#include <sensor/ISensorEventConnection.h>
#include <sensor/Sensor.h>
+#include "android/hardware/BnSensorPrivacyListener.h"
#include <utils/AndroidThreads.h>
#include <utils/KeyedVector.h>
@@ -132,6 +133,30 @@
std::unordered_map<uid_t, bool> mOverrideUids;
};
+ // Sensor privacy allows a user to disable access to all sensors on the device. When
+ // enabled sensor privacy will prevent all apps, including active apps, from accessing
+ // sensors, they will not receive trigger nor on-change events, flush event behavior
+ // does not change, and recurring events are the same as the first one delivered when
+ // sensor privacy was enabled. All sensor direct connections will be stopped as well
+ // and new direct connections will not be allowed while sensor privacy is enabled.
+ // Once sensor privacy is disabled access to sensors will be restored for active
+ // apps, previously stopped direct connections will be restarted, and new direct
+ // connections will be allowed again.
+ class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+ public:
+ explicit SensorPrivacyPolicy(wp<SensorService> service) : mService(service) {}
+ void registerSelf();
+ void unregisterSelf();
+
+ bool isSensorPrivacyEnabled();
+
+ binder::Status onSensorPrivacyChanged(bool enabled);
+
+ private:
+ wp<SensorService> mService;
+ std::atomic_bool mSensorPrivacyEnabled;
+ };
+
enum Mode {
// The regular operating mode where any application can register/unregister/call flush on
// sensors.
@@ -275,6 +300,13 @@
// Prints the shell command help
status_t printHelp(int out);
+ // temporarily stops all active direct connections and disables all sensors
+ void disableAllSensors();
+ void disableAllSensorsLocked();
+ // restarts the previously stopped direct connections and enables all sensors
+ void enableAllSensors();
+ void enableAllSensorsLocked();
+
static uint8_t sHmacGlobalKey[128];
static bool sHmacGlobalKeyIsValid;
@@ -309,6 +341,7 @@
Vector<SensorRegistrationInfo> mLastNSensorRegistrations;
sp<UidPolicy> mUidPolicy;
+ sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
};
} // namespace android
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 22e4d1e..0106b25 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -139,6 +139,7 @@
"Scheduler/DispSyncSource.cpp",
"Scheduler/EventControlThread.cpp",
"Scheduler/EventThread.cpp",
+ "Scheduler/IdleTimer.cpp",
"Scheduler/LayerHistory.cpp",
"Scheduler/MessageQueue.cpp",
"Scheduler/Scheduler.cpp",
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 49e7ef6..1f08f4e 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -48,10 +48,14 @@
namespace impl {
EventThread::EventThread(std::unique_ptr<VSyncSource> src,
- ResyncWithRateLimitCallback resyncWithRateLimitCallback,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
+ const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
+ const InterceptVSyncsCallback& interceptVSyncsCallback,
+ const ResetIdleTimerCallback& resetIdleTimerCallback,
+ const char* threadName)
: EventThread(nullptr, std::move(src), resyncWithRateLimitCallback, interceptVSyncsCallback,
- threadName) {}
+ threadName) {
+ mResetIdleTimer = resetIdleTimerCallback;
+}
EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
@@ -150,6 +154,9 @@
void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
std::lock_guard<std::mutex> lock(mMutex);
+ if (mResetIdleTimer) {
+ mResetIdleTimer();
+ }
if (mResyncWithRateLimitCallback) {
mResyncWithRateLimitCallback();
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 15b5bba..0773c05 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -107,13 +107,15 @@
public:
using ResyncWithRateLimitCallback = std::function<void()>;
using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
+ using ResetIdleTimerCallback = std::function<void()>;
// TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
EventThread(std::unique_ptr<VSyncSource> src,
- ResyncWithRateLimitCallback resyncWithRateLimitCallback,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
+ const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
+ const InterceptVSyncsCallback& interceptVSyncsCallback,
+ const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
~EventThread();
sp<BnDisplayEventConnection> createEventConnection() const override;
@@ -177,6 +179,9 @@
// for debugging
bool mDebugVsyncEnabled GUARDED_BY(mMutex) = false;
+
+ // Callback that resets the idle timer when the next vsync is received.
+ ResetIdleTimerCallback mResetIdleTimer;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Scheduler/IdleTimer.cpp b/services/surfaceflinger/Scheduler/IdleTimer.cpp
new file mode 100644
index 0000000..5a76dbc
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/IdleTimer.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018 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 "IdleTimer.h"
+
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace scheduler {
+
+IdleTimer::IdleTimer(const Interval& interval, const TimeoutCallback& timeoutCallback)
+ : mInterval(interval), mTimeoutCallback(timeoutCallback) {}
+
+IdleTimer::~IdleTimer() {
+ stop();
+}
+
+void IdleTimer::start() {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mState = TimerState::RESET;
+ }
+ mThread = std::thread(&IdleTimer::loop, this);
+}
+
+void IdleTimer::stop() {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mState = TimerState::STOPPED;
+ }
+ mCondition.notify_all();
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+void IdleTimer::loop() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ while (mState != TimerState::STOPPED) {
+ if (mState == TimerState::IDLE) {
+ mCondition.wait(mMutex);
+ } else if (mState == TimerState::RESET) {
+ mState = TimerState::WAITING;
+ if (mCondition.wait_for(mMutex, mInterval) == std::cv_status::timeout) {
+ if (mTimeoutCallback) {
+ mTimeoutCallback();
+ }
+ }
+ if (mState == TimerState::WAITING) {
+ mState = TimerState::IDLE;
+ }
+ }
+ }
+}
+
+void IdleTimer::reset() {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mState = TimerState::RESET;
+ }
+ mCondition.notify_all();
+}
+
+} // namespace scheduler
+} // namespace android
diff --git a/services/surfaceflinger/Scheduler/IdleTimer.h b/services/surfaceflinger/Scheduler/IdleTimer.h
new file mode 100644
index 0000000..aee3fa3
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/IdleTimer.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 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 <chrono>
+#include <condition_variable>
+#include <thread>
+
+#include <android-base/thread_annotations.h>
+
+namespace android {
+namespace scheduler {
+
+/*
+ * Class that sets off a timer for a given interval, and fires a callback when the
+ * interval expires.
+ */
+class IdleTimer {
+public:
+ using Interval = std::chrono::milliseconds;
+ using TimeoutCallback = std::function<void()>;
+
+ IdleTimer(const Interval& interval, const TimeoutCallback& timeoutCallback);
+ ~IdleTimer();
+
+ void start();
+ void stop();
+ void reset();
+
+private:
+ // Enum to track in what state is the timer.
+ enum class TimerState { STOPPED = 0, RESET = 1, WAITING = 2, IDLE = 3 };
+
+ // Function that loops until the condition for stopping is met.
+ void loop();
+
+ // Thread waiting for timer to expire.
+ std::thread mThread;
+
+ // Condition used to notify mThread.
+ std::condition_variable_any mCondition;
+
+ // Lock used for synchronizing the waiting thread with the application thread.
+ std::mutex mMutex;
+
+ TimerState mState GUARDED_BY(mMutex) = TimerState::RESET;
+
+ // Interval after which timer expires.
+ const Interval mInterval;
+
+ // Callback that happens when timer expires.
+ const TimeoutCallback mTimeoutCallback;
+};
+
+} // namespace scheduler
+} // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 5b8cc10..fad56e6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -29,6 +29,7 @@
#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
+#include <cutils/properties.h>
#include <gui/ISurfaceComposer.h>
#include <ui/DisplayStatInfo.h>
#include <utils/Timers.h>
@@ -38,6 +39,7 @@
#include "DispSyncSource.h"
#include "EventControlThread.h"
#include "EventThread.h"
+#include "IdleTimer.h"
#include "InjectVSyncSource.h"
#include "SchedulerUtils.h"
@@ -68,6 +70,17 @@
primaryDispSync->init(mHasSyncFramework, mDispSyncPresentTimeOffset);
mPrimaryDispSync = std::move(primaryDispSync);
mEventControlThread = std::make_unique<impl::EventControlThread>(function);
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.sf.set_idle_timer_ms", value, "0");
+ mSetIdleTimerMs = atoi(value);
+
+ if (mSetIdleTimerMs > 0) {
+ mIdleTimer =
+ std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(mSetIdleTimerMs),
+ [this] { expiredTimerCallback(); });
+ mIdleTimer->start();
+ }
}
Scheduler::~Scheduler() = default;
@@ -98,7 +111,8 @@
std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, sourceName.c_str());
const std::string threadName = connectionName + "Thread";
return std::make_unique<impl::EventThread>(std::move(eventThreadSource), resyncCallback,
- interceptCallback, threadName.c_str());
+ interceptCallback, [this] { resetIdleTimer(); },
+ threadName.c_str());
}
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
@@ -309,4 +323,18 @@
}
}
+void Scheduler::resetIdleTimer() {
+ if (mIdleTimer) {
+ mIdleTimer->reset();
+ ATRACE_INT("ExpiredIdleTimer", 0);
+ }
+}
+
+void Scheduler::expiredTimerCallback() {
+ // TODO(b/113612090): Each time a timer expired, we should record the information into
+ // a circular buffer. Once this has happened a given amount (TBD) of times, we can comfortably
+ // say that the device is sitting in idle.
+ ATRACE_INT("ExpiredIdleTimer", 1);
+}
+
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ea90824..8d4514b 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -25,6 +25,7 @@
#include "DispSync.h"
#include "EventControlThread.h"
#include "EventThread.h"
+#include "IdleTimer.h"
#include "InjectVSyncSource.h"
#include "LayerHistory.h"
#include "SchedulerUtils.h"
@@ -126,6 +127,10 @@
// Collects the average difference between timestamps for each frame regardless
// of which layer the timestamp came from.
void determineTimestampAverage(bool isAutoTimestamp, const nsecs_t framePresentTime);
+ // Function that resets the idle timer.
+ void resetIdleTimer();
+ // Function that is called when the timer expires.
+ void expiredTimerCallback();
// TODO(b/113612090): Instead of letting BufferQueueLayer to access mDispSync directly, it
// should make request to Scheduler to compute next refresh.
@@ -163,6 +168,11 @@
size_t mCounter = 0;
LayerHistory mLayerHistory;
+
+ // Timer that records time between requests for next vsync. If the time is higher than a given
+ // interval, a callback is fired. Set this variable to >0 to use this feature.
+ int64_t mSetIdleTimerMs = 0;
+ std::unique_ptr<scheduler::IdleTimer> mIdleTimer;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 1a13f77..2f35ae5 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -30,6 +30,7 @@
"DisplayTransactionTest.cpp",
"EventControlThreadTest.cpp",
"EventThreadTest.cpp",
+ "IdleTimerTest.cpp",
"LayerHistoryTest.cpp",
"SchedulerTest.cpp",
"SchedulerUtilsTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
new file mode 100644
index 0000000..9fe9a18
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "SchedulerUnittests"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#include "AsyncCallRecorder.h"
+#include "Scheduler/IdleTimer.h"
+
+using namespace std::chrono_literals;
+
+namespace android {
+namespace scheduler {
+
+class IdleTimerTest : public testing::Test {
+protected:
+ IdleTimerTest() = default;
+ ~IdleTimerTest() override = default;
+
+ AsyncCallRecorder<void (*)()> mExpiredTimerCallback;
+
+ std::unique_ptr<IdleTimer> mIdleTimer;
+};
+
+namespace {
+TEST_F(IdleTimerTest, createAndDestroyTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(30ms, [] {});
+}
+
+TEST_F(IdleTimerTest, startStopTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(30ms, mExpiredTimerCallback.getInvocable());
+ mIdleTimer->start();
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ // The timer expires after 30 ms, so the call to the callback should not happen.
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall().has_value());
+ mIdleTimer->stop();
+}
+
+TEST_F(IdleTimerTest, resetTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(20ms, mExpiredTimerCallback.getInvocable());
+ mIdleTimer->start();
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ // The timer expires after 30 ms, so the call to the callback should not happen.
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ mIdleTimer->reset();
+ // The timer was reset, so the call to the callback should not happen.
+ std::this_thread::sleep_for(std::chrono::milliseconds(15));
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ mIdleTimer->stop();
+}
+
+TEST_F(IdleTimerTest, startNotCalledTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mExpiredTimerCallback.getInvocable());
+ std::this_thread::sleep_for(6ms);
+ // The start hasn't happened, so the callback does not happen.
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ mIdleTimer->stop();
+}
+
+TEST_F(IdleTimerTest, idleTimerIdlesTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mExpiredTimerCallback.getInvocable());
+ mIdleTimer->start();
+ std::this_thread::sleep_for(6ms);
+ // The timer expires after 3 ms, so the call to the callback happens.
+ EXPECT_TRUE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ std::this_thread::sleep_for(6ms);
+ // Timer can be idle.
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ // Timer can be reset.
+ mIdleTimer->reset();
+ std::this_thread::sleep_for(6ms);
+ // Timer fires again.
+ EXPECT_TRUE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ mIdleTimer->stop();
+}
+
+TEST_F(IdleTimerTest, timeoutCallbackExecutionTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mExpiredTimerCallback.getInvocable());
+
+ mIdleTimer->start();
+ std::this_thread::sleep_for(6ms);
+ // The timer expires after 3 ms, so the call to the callback should happen.
+ EXPECT_TRUE(mExpiredTimerCallback.waitForCall(1us).has_value());
+ mIdleTimer->stop();
+}
+
+TEST_F(IdleTimerTest, noCallbacksAfterStopAndResetTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mExpiredTimerCallback.getInvocable());
+ mIdleTimer->start();
+ std::this_thread::sleep_for(6ms);
+ EXPECT_TRUE(mExpiredTimerCallback.waitForCall().has_value());
+ mIdleTimer->stop();
+ mIdleTimer->reset();
+ std::this_thread::sleep_for(6ms);
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall().has_value());
+}
+
+TEST_F(IdleTimerTest, noCallbacksAfterStopTest) {
+ mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mExpiredTimerCallback.getInvocable());
+ mIdleTimer->start();
+ std::this_thread::sleep_for(1ms);
+ mIdleTimer->stop();
+ std::this_thread::sleep_for(3ms);
+ EXPECT_FALSE(mExpiredTimerCallback.waitForCall(1us).has_value());
+}
+
+} // namespace
+} // namespace scheduler
+} // namespace android
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_channel.cpp b/services/vr/bufferhubd/buffer_channel.cpp
index cf072b6..695396c 100644
--- a/services/vr/bufferhubd/buffer_channel.cpp
+++ b/services/vr/bufferhubd/buffer_channel.cpp
@@ -32,7 +32,7 @@
: BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
buffer_node_(buffer_node) {
client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
- if (client_state_mask_ == 0ULL) {
+ if (client_state_mask_ == 0U) {
ALOGE("BufferChannel::BufferChannel: %s", strerror(errno));
buffer_node_ = nullptr;
}
@@ -41,7 +41,7 @@
BufferChannel::~BufferChannel() {
ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
channel_id(), buffer_id());
- if (client_state_mask_ != 0ULL) {
+ if (client_state_mask_ != 0U) {
buffer_node_->RemoveClientsBitFromMask(client_state_mask_);
}
Hangup();
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index 158ef9c..c7695bc 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -17,7 +17,7 @@
namespace dvr {
ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
- int channel_id, uint64_t client_state_mask,
+ int channel_id, uint32_t client_state_mask,
const std::shared_ptr<Channel> producer)
: BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
client_state_mask_(client_state_mask),
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_channel.h b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
index 744c095..9888db6 100644
--- a/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
@@ -51,8 +51,8 @@
// The concrete implementation of the Buffer object.
std::shared_ptr<BufferNode> buffer_node_ = nullptr;
- // The state bit of this buffer. Must be one the lower 63 bits.
- uint64_t client_state_mask_ = 0ULL;
+ // The state bit of this buffer.
+ uint32_t client_state_mask_ = 0U;
};
} // namespace dvr
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
index 5fb4ec1..5ee551f 100644
--- a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
@@ -16,14 +16,14 @@
using Message = pdx::Message;
ConsumerChannel(BufferHubService* service, int buffer_id, int channel_id,
- uint64_t client_state_mask,
+ uint32_t client_state_mask,
const std::shared_ptr<Channel> producer);
~ConsumerChannel() override;
bool HandleMessage(Message& message) override;
void HandleImpulse(Message& message) override;
- uint64_t client_state_mask() const { return client_state_mask_; }
+ uint32_t client_state_mask() const { return client_state_mask_; }
BufferInfo GetBufferInfo() const override;
void OnProducerGained();
@@ -39,7 +39,7 @@
pdx::Status<void> OnConsumerRelease(Message& message,
LocalFence release_fence);
- uint64_t client_state_mask_{0};
+ uint32_t client_state_mask_{0U};
bool acquired_{false};
bool released_{true};
std::weak_ptr<Channel> producer_;
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
index 4734439..96ef1a2 100644
--- a/services/vr/bufferhubd/include/private/dvr/producer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
@@ -42,7 +42,7 @@
~ProducerChannel() override;
- uint64_t buffer_state() const {
+ uint32_t buffer_state() const {
return buffer_state_->load(std::memory_order_acquire);
}
@@ -51,18 +51,18 @@
BufferInfo GetBufferInfo() const override;
- BufferDescription<BorrowedHandle> GetBuffer(uint64_t client_state_mask);
+ BufferDescription<BorrowedHandle> GetBuffer(uint32_t client_state_mask);
pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message,
- uint64_t consumer_state_mask);
- pdx::Status<uint64_t> CreateConsumerStateMask();
+ uint32_t consumer_state_mask);
+ pdx::Status<uint32_t> CreateConsumerStateMask();
pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
pdx::Status<void> OnConsumerRelease(Message& message,
LocalFence release_fence);
- void OnConsumerOrphaned(const uint64_t& consumer_state_mask);
+ void OnConsumerOrphaned(const uint32_t& consumer_state_mask);
void AddConsumer(ConsumerChannel* channel);
void RemoveConsumer(ConsumerChannel* channel);
@@ -79,13 +79,13 @@
// IonBuffer that is shared between bufferhubd, producer, and consumers.
IonBuffer metadata_buffer_;
BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
- std::atomic<uint64_t>* buffer_state_ = nullptr;
- std::atomic<uint64_t>* fence_state_ = nullptr;
- std::atomic<uint64_t>* active_clients_bit_mask_ = nullptr;
+ std::atomic<uint32_t>* buffer_state_ = nullptr;
+ std::atomic<uint32_t>* fence_state_ = nullptr;
+ std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
// All orphaned consumer bits. Valid bits are the lower 63 bits, while the
// highest bit is reserved for the producer and should not be set.
- uint64_t orphaned_consumer_bit_mask_{0ULL};
+ uint32_t orphaned_consumer_bit_mask_{0U};
LocalFence post_fence_;
LocalFence returned_fence_;
@@ -110,7 +110,7 @@
// Remove consumer from atomics in shared memory based on consumer_state_mask.
// This function is used for clean up for failures in CreateConsumer method.
- void RemoveConsumerClientMask(uint64_t consumer_state_mask);
+ void RemoveConsumerClientMask(uint32_t consumer_state_mask);
ProducerChannel(const ProducerChannel&) = delete;
void operator=(const ProducerChannel&) = delete;
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index b541fb3..1682bfe 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -93,10 +93,10 @@
// Using placement new here to reuse shared memory instead of new allocation
// and also initialize the value to zero.
buffer_state_ =
- new (&metadata_header_->buffer_state) std::atomic<uint64_t>(0);
- fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint64_t>(0);
+ new (&metadata_header_->buffer_state) std::atomic<uint32_t>(0);
+ fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint32_t>(0);
active_clients_bit_mask_ =
- new (&metadata_header_->active_clients_bit_mask) std::atomic<uint64_t>(0);
+ new (&metadata_header_->active_clients_bit_mask) std::atomic<uint32_t>(0);
// Producer channel is never created after consumer channel, and one buffer
// only have one fixed producer for now. Thus, it is correct to assume
@@ -119,7 +119,7 @@
epoll_event event;
event.events = 0;
- event.data.u64 = 0ULL;
+ event.data.u32 = 0U;
if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_ADD, dummy_fence_fd_.Get(),
&event) < 0) {
ALOGE(
@@ -164,7 +164,7 @@
ProducerChannel::~ProducerChannel() {
ALOGD_IF(TRACE,
"ProducerChannel::~ProducerChannel: channel_id=%d buffer_id=%d "
- "state=%" PRIx64 ".",
+ "state=%" PRIx32 ".",
channel_id(), buffer_id(),
buffer_state_->load(std::memory_order_acquire));
for (auto consumer : consumer_channels_) {
@@ -175,7 +175,7 @@
BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
// Derive the mask of signaled buffers in this producer / consumer set.
- uint64_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
+ uint32_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
for (const ConsumerChannel* consumer : consumer_channels_) {
signaled_mask |= consumer->signaled() ? consumer->client_state_mask() : 0;
}
@@ -228,7 +228,7 @@
}
BufferDescription<BorrowedHandle> ProducerChannel::GetBuffer(
- uint64_t client_state_mask) {
+ uint32_t client_state_mask) {
return {buffer_,
metadata_buffer_,
buffer_id(),
@@ -241,27 +241,27 @@
Status<BufferDescription<BorrowedHandle>> ProducerChannel::OnGetBuffer(
Message& /*message*/) {
ATRACE_NAME("ProducerChannel::OnGetBuffer");
- ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx64 ".",
+ ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx32 ".",
buffer_id(), buffer_state_->load(std::memory_order_acquire));
return {GetBuffer(BufferHubDefs::kFirstClientBitMask)};
}
-Status<uint64_t> ProducerChannel::CreateConsumerStateMask() {
+Status<uint32_t> ProducerChannel::CreateConsumerStateMask() {
// Try find the next consumer state bit which has not been claimed by any
// consumer yet.
// memory_order_acquire is chosen here because all writes in other threads
// that release active_clients_bit_mask_ need to be visible here.
- uint64_t current_active_clients_bit_mask =
+ uint32_t current_active_clients_bit_mask =
active_clients_bit_mask_->load(std::memory_order_acquire);
- uint64_t consumer_state_mask =
+ uint32_t consumer_state_mask =
BufferHubDefs::FindNextAvailableClientStateMask(
current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
- if (consumer_state_mask == 0ULL) {
+ if (consumer_state_mask == 0U) {
ALOGE("%s: reached the maximum mumber of consumers per producer: 63.",
__FUNCTION__);
return ErrorStatus(E2BIG);
}
- uint64_t updated_active_clients_bit_mask =
+ uint32_t updated_active_clients_bit_mask =
current_active_clients_bit_mask | consumer_state_mask;
// Set the updated value only if the current value stays the same as what was
// read before. If the comparison succeeds, update the value without
@@ -274,15 +274,15 @@
while (!active_clients_bit_mask_->compare_exchange_weak(
current_active_clients_bit_mask, updated_active_clients_bit_mask,
std::memory_order_acq_rel, std::memory_order_acquire)) {
- ALOGE("%s: Current active clients bit mask is changed to %" PRIx64
- ", which was expected to be %" PRIx64
+ ALOGE("%s: Current active clients bit mask is changed to %" PRIx32
+ ", which was expected to be %" PRIx32
". Trying to generate a new client state mask to resolve race "
"condition.",
__FUNCTION__, updated_active_clients_bit_mask,
current_active_clients_bit_mask);
consumer_state_mask = BufferHubDefs::FindNextAvailableClientStateMask(
current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
- if (consumer_state_mask == 0ULL) {
+ if (consumer_state_mask == 0U) {
ALOGE("%s: reached the maximum mumber of consumers per producer: %d.",
__FUNCTION__, (BufferHubDefs::kMaxNumberOfClients - 1));
return ErrorStatus(E2BIG);
@@ -294,7 +294,7 @@
return {consumer_state_mask};
}
-void ProducerChannel::RemoveConsumerClientMask(uint64_t consumer_state_mask) {
+void ProducerChannel::RemoveConsumerClientMask(uint32_t consumer_state_mask) {
// Clear up the buffer state and fence state in case there is already
// something there due to possible race condition between producer post and
// consumer failed to create channel.
@@ -308,7 +308,7 @@
}
Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(
- Message& message, uint64_t consumer_state_mask) {
+ Message& message, uint32_t consumer_state_mask) {
ATRACE_NAME(__FUNCTION__);
ALOGD_IF(TRACE, "%s: buffer_id=%d", __FUNCTION__, buffer_id());
@@ -332,7 +332,7 @@
return ErrorStatus(ENOMEM);
}
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (BufferHubDefs::IsBufferReleased(current_buffer_state) ||
BufferHubDefs::AnyClientGained(current_buffer_state)) {
@@ -343,7 +343,7 @@
bool update_buffer_state = true;
if (!BufferHubDefs::IsClientPosted(current_buffer_state,
consumer_state_mask)) {
- uint64_t updated_buffer_state =
+ uint32_t updated_buffer_state =
current_buffer_state ^
(consumer_state_mask & BufferHubDefs::kHighBitsMask);
while (!buffer_state_->compare_exchange_weak(
@@ -351,15 +351,15 @@
std::memory_order_acquire)) {
ALOGI(
"%s: Failed to post to the new consumer. "
- "Current buffer state was changed to %" PRIx64
+ "Current buffer state was changed to %" PRIx32
" when trying to acquire the buffer and modify the buffer state to "
- "%" PRIx64
+ "%" PRIx32
". About to try again if the buffer is still not gained nor fully "
"released.",
__FUNCTION__, current_buffer_state, updated_buffer_state);
if (BufferHubDefs::IsBufferReleased(current_buffer_state) ||
BufferHubDefs::AnyClientGained(current_buffer_state)) {
- ALOGI("%s: buffer is gained or fully released, state=%" PRIx64 ".",
+ ALOGI("%s: buffer is gained or fully released, state=%" PRIx32 ".",
__FUNCTION__, current_buffer_state);
update_buffer_state = false;
break;
@@ -393,7 +393,7 @@
epoll_event event;
event.events = 0;
- event.data.u64 = 0ULL;
+ event.data.u32 = 0U;
int ret = epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
dummy_fence_fd_.Get(), &event);
ALOGE_IF(ret < 0,
@@ -401,7 +401,7 @@
"release fence to include the dummy fence: %s",
strerror(errno));
- eventfd_t dummy_fence_count = 0ULL;
+ eventfd_t dummy_fence_count = 0U;
if (eventfd_read(dummy_fence_fd_.Get(), &dummy_fence_count) < 0) {
const int error = errno;
if (error != EAGAIN) {
@@ -451,13 +451,13 @@
ALOGD_IF(TRACE, "ProducerChannel::OnProducerDetach: buffer_id=%d",
buffer_id());
- uint64_t buffer_state = buffer_state_->load(std::memory_order_acquire);
+ uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
if (!BufferHubDefs::IsClientGained(
buffer_state, BufferHubDefs::kFirstClientStateMask)) {
// Can only detach a BufferProducer when it's in gained state.
ALOGW(
"ProducerChannel::OnProducerDetach: The buffer (id=%d, state=%"
- PRIx64
+ PRIx32
") is not in gained state.",
buffer_id(), buffer_state);
return {};
@@ -534,7 +534,7 @@
}
}
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (BufferHubDefs::IsBufferReleased(current_buffer_state &
~orphaned_consumer_bit_mask_)) {
@@ -542,7 +542,7 @@
if (orphaned_consumer_bit_mask_) {
ALOGW(
"%s: orphaned buffer detected during the this acquire/release cycle: "
- "id=%d orphaned=0x%" PRIx64 " queue_index=%" PRIx64 ".",
+ "id=%d orphaned=0x%" PRIx32 " queue_index=%" PRIx64 ".",
__FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
metadata_header_->queue_index);
orphaned_consumer_bit_mask_ = 0;
@@ -552,16 +552,16 @@
return {};
}
-void ProducerChannel::OnConsumerOrphaned(const uint64_t& consumer_state_mask) {
+void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) {
// Remember the ignored consumer so that newly added consumer won't be
// taking the same state mask as this orphaned consumer.
ALOGE_IF(orphaned_consumer_bit_mask_ & consumer_state_mask,
- "%s: Consumer (consumer_state_mask=%" PRIx64
+ "%s: Consumer (consumer_state_mask=%" PRIx32
") is already orphaned.",
__FUNCTION__, consumer_state_mask);
orphaned_consumer_bit_mask_ |= consumer_state_mask;
- uint64_t current_buffer_state =
+ uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (BufferHubDefs::IsBufferReleased(current_buffer_state &
~orphaned_consumer_bit_mask_)) {
@@ -577,8 +577,8 @@
ALOGW(
"%s: detected new orphaned consumer buffer_id=%d "
- "consumer_state_mask=%" PRIx64 " queue_index=%" PRIx64
- " buffer_state=%" PRIx64 " fence_state=%" PRIx64 ".",
+ "consumer_state_mask=%" PRIx32 " queue_index=%" PRIx64
+ " buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
__FUNCTION__, buffer_id(), consumer_state_mask,
metadata_header_->queue_index,
buffer_state_->load(std::memory_order_acquire),
@@ -594,18 +594,18 @@
std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
// Restore the consumer state bit and make it visible in other threads that
// acquire the active_clients_bit_mask_.
- uint64_t consumer_state_mask = channel->client_state_mask();
- uint64_t current_active_clients_bit_mask =
+ uint32_t consumer_state_mask = channel->client_state_mask();
+ uint32_t current_active_clients_bit_mask =
active_clients_bit_mask_->load(std::memory_order_acquire);
- uint64_t updated_active_clients_bit_mask =
+ uint32_t updated_active_clients_bit_mask =
current_active_clients_bit_mask & (~consumer_state_mask);
while (!active_clients_bit_mask_->compare_exchange_weak(
current_active_clients_bit_mask, updated_active_clients_bit_mask,
std::memory_order_acq_rel, std::memory_order_acquire)) {
ALOGI(
"%s: Failed to remove consumer state mask. Current active clients bit "
- "mask is changed to %" PRIu64
- " when trying to acquire and modify it to %" PRIu64
+ "mask is changed to %" PRIx32
+ " when trying to acquire and modify it to %" PRIx32
". About to try again.",
__FUNCTION__, current_active_clients_bit_mask,
updated_active_clients_bit_mask);
@@ -613,7 +613,7 @@
current_active_clients_bit_mask & (~consumer_state_mask);
}
- const uint64_t current_buffer_state =
+ const uint32_t current_buffer_state =
buffer_state_->load(std::memory_order_acquire);
if (BufferHubDefs::IsClientPosted(current_buffer_state,
consumer_state_mask) ||
@@ -634,7 +634,7 @@
if (fence_state_->load(std::memory_order_acquire) & consumer_state_mask) {
epoll_event event;
event.events = EPOLLIN;
- event.data.u64 = consumer_state_mask;
+ event.data.u32 = consumer_state_mask;
if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
dummy_fence_fd_.Get(), &event) < 0) {
ALOGE(