Merge changes from topic "gpustats-statsd-2"
* changes:
Game Driver Metrics: apply worst case limits for stats tracking
Game Driver Metrics: plumb gpu app stats into statsd
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 21de4db..0cf2df0 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -54,7 +54,9 @@
#include <android/os/IIncidentCompanion.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
+#include <debuggerd/client.h>
#include <dumpsys.h>
+#include <dumputils/dump_utils.h>
#include <hidl/ServiceManagement.h>
#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
@@ -1184,6 +1186,15 @@
}
static void DumpHals() {
+ if (!ds.IsZipping()) {
+ RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
+ CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
+ return;
+ }
+ DurationReporter duration_reporter("DUMP HALS");
+ RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
+ CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+
using android::hidl::manager::V1_0::IServiceManager;
using android::hardware::defaultServiceManager;
@@ -1260,14 +1271,7 @@
{"ps", "-A", "-T", "-Z", "-O", "pri,nice,rtprio,sched,pcy,time"});
RunCommand("LIBRANK", {"librank"}, CommandOptions::AS_ROOT);
- if (ds.IsZipping()) {
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
- CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
- DumpHals();
- } else {
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
- CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
- }
+ DumpHals();
RunCommand("PRINTENV", {"printenv"});
RunCommand("NETSTAT", {"netstat", "-nW"});
@@ -1450,7 +1454,7 @@
RunDumpsysCritical();
/* collect stack traces from Dalvik and native processes (needs root) */
- dump_traces_path = dump_traces();
+ dump_traces_path = ds.DumpTraces();
/* Run some operations that require root. */
ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping());
@@ -1573,20 +1577,121 @@
RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
SEC_TO_MSEC(10));
- if (ds.IsZipping()) {
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
- CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
- DumpHals();
- } else {
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
- CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
- }
+ DumpHals();
printf("========================================================\n");
printf("== dumpstate: done (id %d)\n", ds.id_);
printf("========================================================\n");
}
+const char* Dumpstate::DumpTraces() {
+ DurationReporter duration_reporter("DUMP TRACES");
+
+ const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
+ const size_t buf_size = temp_file_pattern.length() + 1;
+ std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
+ memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);
+
+ // Create a new, empty file to receive all trace dumps.
+ //
+ // TODO: This can be simplified once we remove support for the old style
+ // dumps. We can have a file descriptor passed in to dump_traces instead
+ // of creating a file, closing it and then reopening it again.
+ android::base::unique_fd fd(mkostemp(file_name_buf.get(), O_APPEND | O_CLOEXEC));
+ if (fd < 0) {
+ MYLOGE("mkostemp on pattern %s: %s\n", file_name_buf.get(), strerror(errno));
+ return nullptr;
+ }
+
+ // Nobody should have access to this temporary file except dumpstate, but we
+ // temporarily grant 'read' to 'others' here because this file is created
+ // when tombstoned is still running as root, but dumped after dropping. This
+ // can go away once support for old style dumping has.
+ const int chmod_ret = fchmod(fd, 0666);
+ if (chmod_ret < 0) {
+ MYLOGE("fchmod on %s failed: %s\n", file_name_buf.get(), strerror(errno));
+ return nullptr;
+ }
+
+ std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
+ if (proc.get() == nullptr) {
+ MYLOGE("opendir /proc failed: %s\n", strerror(errno));
+ return nullptr;
+ }
+
+ // Number of times process dumping has timed out. If we encounter too many
+ // failures, we'll give up.
+ int timeout_failures = 0;
+ bool dalvik_found = false;
+
+ const std::set<int> hal_pids = get_interesting_hal_pids();
+
+ struct dirent* d;
+ while ((d = readdir(proc.get()))) {
+ int pid = atoi(d->d_name);
+ if (pid <= 0) {
+ continue;
+ }
+
+ const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
+ std::string exe;
+ if (!android::base::Readlink(link_name, &exe)) {
+ continue;
+ }
+
+ bool is_java_process;
+ if (exe == "/system/bin/app_process32" || exe == "/system/bin/app_process64") {
+ // Don't bother dumping backtraces for the zygote.
+ if (IsZygote(pid)) {
+ continue;
+ }
+
+ dalvik_found = true;
+ is_java_process = true;
+ } else if (should_dump_native_traces(exe.c_str()) || hal_pids.find(pid) != hal_pids.end()) {
+ is_java_process = false;
+ } else {
+ // Probably a native process we don't care about, continue.
+ continue;
+ }
+
+ // If 3 backtrace dumps fail in a row, consider debuggerd dead.
+ if (timeout_failures == 3) {
+ dprintf(fd, "ERROR: Too many stack dump failures, exiting.\n");
+ break;
+ }
+
+ const uint64_t start = Nanotime();
+ const int ret = dump_backtrace_to_file_timeout(
+ pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace,
+ is_java_process ? 5 : 20, fd);
+
+ if (ret == -1) {
+ // For consistency, the header and footer to this message match those
+ // dumped by debuggerd in the success case.
+ dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
+ dprintf(fd, "Dump failed, likely due to a timeout.\n");
+ dprintf(fd, "---- end %d ----", pid);
+ timeout_failures++;
+ continue;
+ }
+
+ // We've successfully dumped stack traces, reset the failure count
+ // and write a summary of the elapsed time to the file and continue with the
+ // next process.
+ timeout_failures = 0;
+
+ dprintf(fd, "[dump %s stack %d: %.3fs elapsed]\n", is_java_process ? "dalvik" : "native",
+ pid, (float)(Nanotime() - start) / NANOS_PER_SEC);
+ }
+
+ if (!dalvik_found) {
+ MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
+ }
+
+ return file_name_buf.release();
+}
+
void Dumpstate::DumpstateBoard() {
DurationReporter duration_reporter("dumpstate_board()");
printf("========================================================\n");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index c326bb6..603af71 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -73,13 +73,13 @@
*/
class DurationReporter {
public:
- explicit DurationReporter(const std::string& title, bool log_only = false);
+ explicit DurationReporter(const std::string& title, bool logcat_only = false);
~DurationReporter();
private:
std::string title_;
- bool log_only_;
+ bool logcat_only_;
uint64_t started_;
DISALLOW_COPY_AND_ASSIGN(DurationReporter);
@@ -291,6 +291,9 @@
// TODO: temporary method until Dumpstate object is properly set
void SetProgress(std::unique_ptr<Progress> progress);
+ // Dumps Dalvik and native stack traces, return the trace file location (nullptr if none).
+ const char* DumpTraces();
+
void DumpstateBoard();
/*
@@ -543,9 +546,6 @@
/* create leading directories, if necessary */
void create_parent_dirs(const char *path);
-/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
-const char *dump_traces();
-
/* for each process in the system, run the specified function */
void for_each_pid(for_each_pid_func func, const char *header);
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 2a5516d..8b92988 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -50,8 +50,6 @@
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
-#include <debuggerd/client.h>
-#include <dumputils/dump_utils.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -95,8 +93,8 @@
return singleton_;
}
-DurationReporter::DurationReporter(const std::string& title, bool log_only)
- : title_(title), log_only_(log_only) {
+DurationReporter::DurationReporter(const std::string& title, bool logcat_only)
+ : title_(title), logcat_only_(logcat_only) {
if (!title_.empty()) {
started_ = Nanotime();
}
@@ -105,15 +103,13 @@
DurationReporter::~DurationReporter() {
if (!title_.empty()) {
uint64_t elapsed = Nanotime() - started_;
- if (log_only_) {
- MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
- } else {
- // TODO(124089395): Remove or rewrite when bugreport latency is fixed.
- MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
- // Use "Yoda grammar" to make it easier to grep|sort sections.
- printf("------ %.3fs was the duration of '%s' ------\n", (float)elapsed / NANOS_PER_SEC,
- title_.c_str());
+ MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
+ if (logcat_only_) {
+ return;
}
+ // Use "Yoda grammar" to make it easier to grep|sort sections.
+ printf("------ %.3fs was the duration of '%s' ------\n", (float)elapsed / NANOS_PER_SEC,
+ title_.c_str());
}
}
@@ -795,115 +791,6 @@
return _redirect_to_file(redirect, path, O_APPEND);
}
-// Dump Dalvik and native stack traces, return the trace file location (nullptr if none).
-const char* dump_traces() {
- DurationReporter duration_reporter("DUMP TRACES");
-
- const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
- const size_t buf_size = temp_file_pattern.length() + 1;
- std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
- memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);
-
- // Create a new, empty file to receive all trace dumps.
- //
- // TODO: This can be simplified once we remove support for the old style
- // dumps. We can have a file descriptor passed in to dump_traces instead
- // of creating a file, closing it and then reopening it again.
- android::base::unique_fd fd(mkostemp(file_name_buf.get(), O_APPEND | O_CLOEXEC));
- if (fd < 0) {
- MYLOGE("mkostemp on pattern %s: %s\n", file_name_buf.get(), strerror(errno));
- return nullptr;
- }
-
- // Nobody should have access to this temporary file except dumpstate, but we
- // temporarily grant 'read' to 'others' here because this file is created
- // when tombstoned is still running as root, but dumped after dropping. This
- // can go away once support for old style dumping has.
- const int chmod_ret = fchmod(fd, 0666);
- if (chmod_ret < 0) {
- MYLOGE("fchmod on %s failed: %s\n", file_name_buf.get(), strerror(errno));
- return nullptr;
- }
-
- std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
- if (proc.get() == nullptr) {
- MYLOGE("opendir /proc failed: %s\n", strerror(errno));
- return nullptr;
- }
-
- // Number of times process dumping has timed out. If we encounter too many
- // failures, we'll give up.
- int timeout_failures = 0;
- bool dalvik_found = false;
-
- const std::set<int> hal_pids = get_interesting_hal_pids();
-
- struct dirent* d;
- while ((d = readdir(proc.get()))) {
- int pid = atoi(d->d_name);
- if (pid <= 0) {
- continue;
- }
-
- const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
- std::string exe;
- if (!android::base::Readlink(link_name, &exe)) {
- continue;
- }
-
- bool is_java_process;
- if (exe == "/system/bin/app_process32" || exe == "/system/bin/app_process64") {
- // Don't bother dumping backtraces for the zygote.
- if (IsZygote(pid)) {
- continue;
- }
-
- dalvik_found = true;
- is_java_process = true;
- } else if (should_dump_native_traces(exe.c_str()) || hal_pids.find(pid) != hal_pids.end()) {
- is_java_process = false;
- } else {
- // Probably a native process we don't care about, continue.
- continue;
- }
-
- // If 3 backtrace dumps fail in a row, consider debuggerd dead.
- if (timeout_failures == 3) {
- dprintf(fd, "ERROR: Too many stack dump failures, exiting.\n");
- break;
- }
-
- const uint64_t start = Nanotime();
- const int ret = dump_backtrace_to_file_timeout(
- pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace,
- is_java_process ? 5 : 20, fd);
-
- if (ret == -1) {
- // For consistency, the header and footer to this message match those
- // dumped by debuggerd in the success case.
- dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
- dprintf(fd, "Dump failed, likely due to a timeout.\n");
- dprintf(fd, "---- end %d ----", pid);
- timeout_failures++;
- continue;
- }
-
- // We've successfully dumped stack traces, reset the failure count
- // and write a summary of the elapsed time to the file and continue with the
- // next process.
- timeout_failures = 0;
-
- dprintf(fd, "[dump %s stack %d: %.3fs elapsed]\n", is_java_process ? "dalvik" : "native",
- pid, (float)(Nanotime() - start) / NANOS_PER_SEC);
- }
-
- if (!dalvik_found) {
- MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
- }
-
- return file_name_buf.release();
-}
-
void dump_route_tables() {
DurationReporter duration_reporter("DUMP ROUTE TABLES");
if (PropertiesHelper::IsDryRun()) return;
diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS
index 5d4f176..5673918 100644
--- a/cmds/installd/OWNERS
+++ b/cmds/installd/OWNERS
@@ -3,6 +3,8 @@
agampe@google.com
calin@google.com
jsharkey@android.com
+maco@google.com
mathieuc@google.com
+narayan@google.com
ngeoffray@google.com
toddke@google.com
diff --git a/cmds/installd/globals.cpp b/cmds/installd/globals.cpp
index f52c2e7..1394701 100644
--- a/cmds/installd/globals.cpp
+++ b/cmds/installd/globals.cpp
@@ -44,7 +44,7 @@
static constexpr const char* PRIVATE_APP_SUBDIR = "app-private/"; // sub-directory under
// ANDROID_DATA
-static constexpr const char* STAGING_SUBDIR = "pkg_staging/"; // sub-directory under ANDROID_DATA
+static constexpr const char* STAGING_SUBDIR = "app-staging/"; // sub-directory under ANDROID_DATA
std::string android_app_dir;
std::string android_app_ephemeral_dir;
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index 34a3fdc..d5dc6b7 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -232,7 +232,6 @@
else if (strcmp(key, "categories") == 0)
{
char* context2 = nullptr;
- int categoryCount = 0;
categories[categoryCount] = strtok_r(value, ",", &context2);
while (categories[categoryCount] != nullptr)
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
index b82141c..83a1048 100644
--- a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -106,28 +106,37 @@
virtual bool isRemote() = 0;
/**
- * Dumps information about the interface.
+ * Dumps information about the interface. By default, dumps nothing.
*/
- virtual binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
- return STATUS_OK;
- }
+ virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
+
+ /**
+ * Interprets this binder as this underlying interface if this has stored an ICInterface in the
+ * binder's user data.
+ *
+ * This does not do type checking and should only be used when the binder is known to originate
+ * from ICInterface. Most likely, you want to use I*::fromBinder.
+ */
+ static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);
/**
* Helper method to create a class
*/
- static AIBinder_Class* defineClass(const char* interfaceDescriptor,
- AIBinder_Class_onCreate onCreate,
- AIBinder_Class_onDestroy onDestroy,
- AIBinder_Class_onTransact onTransact,
- AIBinder_onDump onDump = nullptr) {
- AIBinder_Class* clazz =
- AIBinder_Class_define(interfaceDescriptor, onCreate, onDestroy, onTransact);
- if (clazz == nullptr) {
- return nullptr;
- }
- AIBinder_Class_setOnDump(clazz, onDump);
- return clazz;
- }
+ static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
+ AIBinder_Class_onTransact onTransact);
+
+ private:
+ class ICInterfaceData {
+ public:
+ std::shared_ptr<ICInterface> interface;
+
+ static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);
+
+ static inline void* onCreate(void* args);
+ static inline void onDestroy(void* userData);
+ static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
+ uint32_t numArgs);
+ };
};
/**
@@ -141,7 +150,7 @@
SpAIBinder asBinder() override;
- bool isRemote() override { return true; }
+ bool isRemote() override { return false; }
protected:
/**
@@ -176,6 +185,55 @@
SpAIBinder mBinder;
};
+// END OF CLASS DECLARATIONS
+
+binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
+ return STATUS_OK;
+}
+
+std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
+ return ICInterfaceData::getInterface(binder);
+}
+
+AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
+ AIBinder_Class_onTransact onTransact) {
+ AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
+ ICInterfaceData::onDestroy, onTransact);
+ if (clazz == nullptr) {
+ return nullptr;
+ }
+
+ // We can't know if this method is overriden by a subclass interface, so we must register
+ // ourselves. The default (nothing to dump) is harmless.
+ AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
+ return clazz;
+}
+
+std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
+ if (binder == nullptr) return nullptr;
+
+ void* userData = AIBinder_getUserData(binder);
+ if (userData == nullptr) return nullptr;
+
+ return static_cast<ICInterfaceData*>(userData)->interface;
+}
+
+void* ICInterface::ICInterfaceData::onCreate(void* args) {
+ std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
+ ICInterfaceData* data = new ICInterfaceData{interface};
+ return static_cast<void*>(data);
+}
+
+void ICInterface::ICInterfaceData::onDestroy(void* userData) {
+ delete static_cast<ICInterfaceData*>(userData);
+}
+
+binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
+ uint32_t numArgs) {
+ std::shared_ptr<ICInterface> interface = getInterface(binder);
+ return interface->dump(fd, args, numArgs);
+}
+
template <typename INTERFACE>
SpAIBinder BnCInterface<INTERFACE>::asBinder() {
std::lock_guard<std::mutex> l(mMutex);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 400daf0..247dc8d 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -860,6 +860,59 @@
}
return reply.readInt32();
}
+
+ virtual status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
+ bool* outSupport) const {
+ Parcel data, reply;
+ status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (error != NO_ERROR) {
+ ALOGE("getDisplayBrightnessSupport: failed to write interface token: %d", error);
+ return error;
+ }
+ error = data.writeStrongBinder(displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("getDisplayBrightnessSupport: failed to write display token: %d", error);
+ return error;
+ }
+ error = remote()->transact(BnSurfaceComposer::GET_DISPLAY_BRIGHTNESS_SUPPORT, data, &reply);
+ if (error != NO_ERROR) {
+ ALOGE("getDisplayBrightnessSupport: failed to transact: %d", error);
+ return error;
+ }
+ bool support;
+ error = reply.readBool(&support);
+ if (error != NO_ERROR) {
+ ALOGE("getDisplayBrightnessSupport: failed to read support: %d", error);
+ return error;
+ }
+ *outSupport = support;
+ return NO_ERROR;
+ }
+
+ virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const {
+ Parcel data, reply;
+ status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to write interface token: %d", error);
+ return error;
+ }
+ error = data.writeStrongBinder(displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to write display token: %d", error);
+ return error;
+ }
+ error = data.writeFloat(brightness);
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to write brightness: %d", error);
+ return error;
+ }
+ error = remote()->transact(BnSurfaceComposer::SET_DISPLAY_BRIGHTNESS, data, &reply);
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to transact: %d", error);
+ return error;
+ }
+ return NO_ERROR;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1390,6 +1443,35 @@
reply->writeInt32(result);
return result;
}
+ case GET_DISPLAY_BRIGHTNESS_SUPPORT: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> displayToken;
+ status_t error = data.readNullableStrongBinder(&displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("getDisplayBrightnessSupport: failed to read display token: %d", error);
+ return error;
+ }
+ bool support = false;
+ error = getDisplayBrightnessSupport(displayToken, &support);
+ reply->writeBool(support);
+ return error;
+ }
+ case SET_DISPLAY_BRIGHTNESS: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> displayToken;
+ status_t error = data.readNullableStrongBinder(&displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to read display token: %d", error);
+ return error;
+ }
+ float brightness = -1.0f;
+ error = data.readFloat(&brightness);
+ if (error != NO_ERROR) {
+ ALOGE("setDisplayBrightness: failed to read brightness: %d", error);
+ return error;
+ }
+ return setDisplayBrightness(displayToken, brightness);
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index af6373d..6460325 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -467,7 +467,15 @@
char message[64];
std::lock_guard<std::mutex> lock(mMutex);
- snprintf(message, sizeof(message), "Trace fence %u", mFencesQueued);
+ if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
+ snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
+ ATRACE_NAME(message);
+ // Need an increment on both to make the trace number correct.
+ mFencesQueued++;
+ mFencesSignaled++;
+ return;
+ }
+ snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
ATRACE_NAME(message);
mQueue.push_back(fence);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d6708ab..b0e8275 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1503,6 +1503,17 @@
return ComposerService::getComposerService()->removeRegionSamplingListener(listener);
}
+bool SurfaceComposerClient::getDisplayBrightnessSupport(const sp<IBinder>& displayToken) {
+ bool support = false;
+ ComposerService::getComposerService()->getDisplayBrightnessSupport(displayToken, &support);
+ return support;
+}
+
+status_t SurfaceComposerClient::setDisplayBrightness(const sp<IBinder>& displayToken,
+ float brightness) {
+ return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness);
+}
+
// ----------------------------------------------------------------------------
status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 0e576ca..3dffa8f 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -376,6 +376,37 @@
*/
virtual status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
std::vector<int32_t>* outAllowedConfigs) = 0;
+ /*
+ * Gets whether brightness operations are supported on a display.
+ *
+ * displayToken
+ * The token of the display.
+ * outSupport
+ * An output parameter for whether brightness operations are supported.
+ *
+ * Returns NO_ERROR upon success. Otherwise,
+ * NAME_NOT_FOUND if the display is invalid, or
+ * BAD_VALUE if the output parameter is invalid.
+ */
+ virtual status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
+ bool* outSupport) const = 0;
+
+ /*
+ * Sets the brightness of a display.
+ *
+ * displayToken
+ * The token of the display whose brightness is set.
+ * brightness
+ * A number between 0.0f (minimum brightness) and 1.0 (maximum brightness), or -1.0f to
+ * turn the backlight off.
+ *
+ * Returns NO_ERROR upon success. Otherwise,
+ * NAME_NOT_FOUND if the display is invalid, or
+ * BAD_VALUE if the brightness is invalid, or
+ * INVALID_OPERATION if brightness operations are not supported.
+ */
+ virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken,
+ float brightness) const = 0;
};
// ----------------------------------------------------------------------------
@@ -425,6 +456,8 @@
REMOVE_REGION_SAMPLING_LISTENER,
SET_ALLOWED_DISPLAY_CONFIGS,
GET_ALLOWED_DISPLAY_CONFIGS,
+ GET_DISPLAY_BRIGHTNESS_SUPPORT,
+ SET_DISPLAY_BRIGHTNESS,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 48c978f..39d6d13 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -168,6 +168,32 @@
// Queries whether a given display is wide color display.
static status_t isWideColorDisplay(const sp<IBinder>& display, bool* outIsWideColorDisplay);
+ /*
+ * Returns whether brightness operations are supported on a display.
+ *
+ * displayToken
+ * The token of the display.
+ *
+ * Returns whether brightness operations are supported on a display or not.
+ */
+ static bool getDisplayBrightnessSupport(const sp<IBinder>& displayToken);
+
+ /*
+ * Sets the brightness of a display.
+ *
+ * displayToken
+ * The token of the display whose brightness is set.
+ * brightness
+ * A number between 0.0 (minimum brightness) and 1.0 (maximum brightness), or -1.0f to
+ * turn the backlight off.
+ *
+ * Returns NO_ERROR upon success. Otherwise,
+ * NAME_NOT_FOUND if the display handle is invalid, or
+ * BAD_VALUE if the brightness value is invalid, or
+ * INVALID_OPERATION if brightness operaetions are not supported.
+ */
+ static status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness);
+
// ------------------------------------------------------------------------
// surface creation / destruction
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index a7599e0..06fe86c 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -669,6 +669,14 @@
status_t getProtectedContentSupport(bool* /*outSupported*/) const override { return NO_ERROR; }
status_t isWideColorDisplay(const sp<IBinder>&, bool*) const override { return NO_ERROR; }
+ status_t getDisplayBrightnessSupport(const sp<IBinder>& /*displayToken*/,
+ bool* /*outSupport*/) const override {
+ return NO_ERROR;
+ }
+ status_t setDisplayBrightness(const sp<IBinder>& /*displayToken*/,
+ float /*brightness*/) const override {
+ return NO_ERROR;
+ }
status_t addRegionSamplingListener(const Rect& /*samplingArea*/,
const sp<IBinder>& /*stopLayerHandle*/,
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 538d728..cd0ea5d 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -100,7 +100,7 @@
return NO_ERROR;
}
- if (mService->isOperationRestricted(mOpPackageName)) {
+ if (!mService->isOperationPermitted(mOpPackageName)) {
return PERMISSION_DENIED;
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 9a37ff1..3fbd61e 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1691,13 +1691,13 @@
return (packageName.contains(mWhiteListedPackage.string()));
}
-bool SensorService::isOperationRestricted(const String16& opPackageName) {
+bool SensorService::isOperationPermitted(const String16& opPackageName) {
Mutex::Autolock _l(mLock);
- if (mCurrentOperatingMode != RESTRICTED) {
+ if (mCurrentOperatingMode == RESTRICTED) {
String8 package(opPackageName);
- return !isWhiteListedPackage(package);
+ return isWhiteListedPackage(package);
}
- return false;
+ return true;
}
void SensorService::UidPolicy::registerSelf() {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 136ee27..fbfe05d 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -272,7 +272,7 @@
// allowed to register for or call flush on sensors. Typically only cts test packages are
// allowed.
bool isWhiteListedPackage(const String8& packageName);
- bool isOperationRestricted(const String16& opPackageName);
+ bool isOperationPermitted(const String16& opPackageName);
// Reset the state of SensorService to NORMAL mode.
status_t resetToNormalMode();
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index b2383ad..3713121 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -345,6 +345,14 @@
return parentBounds;
}
+void BufferStateLayer::setPostTime(nsecs_t postTime) {
+ mFlinger->mTimeStats->setPostTime(getSequence(), getFrameNumber(), getName().c_str(), postTime);
+}
+
+void BufferStateLayer::setDesiredPresentTime(nsecs_t desiredPresentTime) {
+ mDesiredPresentTime = desiredPresentTime;
+}
+
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
@@ -359,8 +367,7 @@
}
nsecs_t BufferStateLayer::getDesiredPresentTime() {
- // TODO(marissaw): support an equivalent to desiredPresentTime for timestats metrics
- return 0;
+ return mDesiredPresentTime;
}
std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
@@ -532,8 +539,6 @@
}
}
- // TODO(marissaw): properly support mTimeStats
- mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 97662e8..668830a 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -89,6 +89,9 @@
Rect getBufferSize(const State& s) const override;
FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
+
+ void setPostTime(nsecs_t postTime) override;
+ void setDesiredPresentTime(nsecs_t desiredPresentTime) override;
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
@@ -149,6 +152,8 @@
bool mReleasePreviousBuffer = false;
nsecs_t mCallbackHandleAcquireTime = -1;
+ nsecs_t mDesiredPresentTime = -1;
+
// TODO(marissaw): support sticky transform for LEGACY camera mode
};
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index a2692bc..3364399 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -79,6 +79,18 @@
return true;
}
+bool ColorLayer::setDataspace(ui::Dataspace dataspace) {
+ if (mCurrentState.dataspace == dataspace) {
+ return false;
+ }
+
+ mCurrentState.sequence++;
+ mCurrentState.dataspace = dataspace;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display,
const ui::Transform& transform, const Rect& viewport,
int32_t /* supportedPerFrameMetadata */,
@@ -148,6 +160,11 @@
layerCompositionState.surfaceDamage = surfaceDamageRegion;
}
+void ColorLayer::commitTransaction(const State& stateToCommit) {
+ Layer::commitTransaction(stateToCommit);
+ mCurrentDataSpace = mDrawingState.dataspace;
+}
+
std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() const {
return mCompositionLayer;
}
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 9a72b40..bd83d1a 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -35,10 +35,14 @@
bool setColor(const half3& color) override;
+ bool setDataspace(ui::Dataspace dataspace) override;
+
void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
const Rect& viewport, int32_t supportedPerFrameMetadata,
const ui::Dataspace targetDataspace) override;
+ void commitTransaction(const State& stateToCommit) override;
+
bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
protected:
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 885cdd4..94349de 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -65,6 +65,8 @@
MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+ MOCK_METHOD2(setDisplayBrightness, status_t(DisplayId, float));
+ MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
MOCK_METHOD2(onHotplug,
std::optional<DisplayIdentificationInfo>(hwc2_display_t, HWC2::Connection));
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 8343e5a..9cb43bc 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -214,7 +214,6 @@
[&](const auto& tmpCapabilities) {
capabilities = tmpCapabilities;
});
-
return capabilities;
}
@@ -1159,6 +1158,30 @@
return Error::NONE;
}
+Error Composer::getDisplayBrightnessSupport(Display display, bool* outSupport) {
+ if (!mClient_2_3) {
+ return Error::UNSUPPORTED;
+ }
+ Error error = kDefaultError;
+ mClient_2_3->getDisplayBrightnessSupport(display,
+ [&](const auto& tmpError, const auto& tmpSupport) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outSupport = tmpSupport;
+ });
+ return error;
+}
+
+Error Composer::setDisplayBrightness(Display display, float brightness) {
+ if (!mClient_2_3) {
+ return Error::UNSUPPORTED;
+ }
+ return mClient_2_3->setDisplayBrightness(display, brightness);
+}
+
CommandReader::~CommandReader()
{
resetData();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 542e840..e24db15 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -203,6 +203,8 @@
std::vector<DisplayCapability>* outCapabilities) = 0;
virtual Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer, const std::vector<PerFrameMetadataBlob>& metadata) = 0;
+ virtual Error getDisplayBrightnessSupport(Display display, bool* outSupport) = 0;
+ virtual Error setDisplayBrightness(Display display, float brightness) = 0;
};
namespace impl {
@@ -414,6 +416,8 @@
Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override;
+ Error getDisplayBrightnessSupport(Display display, bool* outSupport) override;
+ Error setDisplayBrightness(Display display, float brightness) override;
private:
class CommandWriter : public CommandWriterBase {
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 910a527..62073b6 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -277,6 +277,11 @@
if (error == Error::None && dozeSupport) {
mDisplayCapabilities.emplace(DisplayCapability::Doze);
}
+ bool brightnessSupport = false;
+ error = static_cast<Error>(mComposer.getDisplayBrightnessSupport(mId, &brightnessSupport));
+ if (error == Error::None && brightnessSupport) {
+ mDisplayCapabilities.emplace(DisplayCapability::Brightness);
+ }
}
ALOGV("Created display %" PRIu64, id);
}
@@ -710,6 +715,11 @@
return error;
}
+Error Display::setDisplayBrightness(float brightness) const {
+ auto intError = mComposer.setDisplayBrightness(mId, brightness);
+ return static_cast<Error>(intError);
+}
+
// For use by Device
void Display::setConnected(bool connected) {
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index f96614f..4209e45 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -264,6 +264,7 @@
[[clang::warn_unused_result]] virtual Error presentOrValidate(
uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
+ [[clang::warn_unused_result]] virtual Error setDisplayBrightness(float brightness) const = 0;
};
namespace impl {
@@ -322,6 +323,7 @@
Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence, uint32_t* state) override;
+ Error setDisplayBrightness(float brightness) const override;
// Other Display methods
hwc2_display_t getId() const override { return mId; }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 3b9e0e6..1099041 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -784,6 +784,19 @@
return NO_ERROR;
}
+status_t HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ const auto error = mDisplayData[displayId].hwcDisplay->setDisplayBrightness(brightness);
+ if (error == HWC2::Error::Unsupported) {
+ RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ }
+ if (error == HWC2::Error::BadParameter) {
+ RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ }
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+}
+
bool HWComposer::isUsingVrComposer() const {
return getComposer()->isUsingVrComposer();
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index ca59a26..de863b8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -140,6 +140,9 @@
uint64_t timestamp,
DisplayedFrameStats* outStats) = 0;
+ // Sets the brightness of a display.
+ virtual status_t setDisplayBrightness(DisplayId displayId, float brightness) = 0;
+
// Events handling ---------------------------------------------------------
// Returns stable display ID (and display name on connection of new or previously disconnected
@@ -271,6 +274,7 @@
uint8_t componentMask, uint64_t maxFrames) override;
status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) override;
+ status_t setDisplayBrightness(DisplayId displayId, float brightness) override;
// Events handling ---------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 1afb917..79d2238 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -182,6 +182,9 @@
bool inputInfoChanged;
InputWindowInfo inputInfo;
+ // dataspace is only used by BufferStateLayer and ColorLayer
+ ui::Dataspace dataspace;
+
// The fields below this point are only used by BufferStateLayer
Geometry active;
@@ -193,7 +196,6 @@
sp<GraphicBuffer> buffer;
sp<Fence> acquireFence;
- ui::Dataspace dataspace;
HdrMetadata hdrMetadata;
Region surfaceDamageRegion;
int32_t api;
@@ -432,6 +434,9 @@
}
virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
+ virtual void setPostTime(nsecs_t /*postTime*/) {}
+ virtual void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/) {}
+
protected:
virtual bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform, Region& clearRegion,
@@ -691,7 +696,7 @@
// For unit tests
friend class TestableSurfaceFlinger;
- void commitTransaction(const State& stateToCommit);
+ virtual void commitTransaction(const State& stateToCommit);
uint32_t getEffectiveUsage(uint32_t usage) const;
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index 5178836..1eccf9a 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -76,18 +76,9 @@
void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
if (mTraceDetailedInfo) ATRACE_CALL();
Mutex::Autolock lock(mMutex);
-
+ mPeriod = period;
mPhase = phase;
mReferenceTime = referenceTime;
- if (mPeriod != period && mReferenceTime != 0) {
- // Inflate the reference time to be the most recent predicted
- // vsync before the current time.
- const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const nsecs_t baseTime = now - mReferenceTime;
- const nsecs_t numOldPeriods = baseTime / mPeriod;
- mReferenceTime = mReferenceTime + (numOldPeriods)*mPeriod;
- }
- mPeriod = period;
if (mTraceDetailedInfo) {
ATRACE_INT64("DispSync:Period", mPeriod);
ATRACE_INT64("DispSync:Phase", mPhase + mPeriod / 2);
@@ -438,16 +429,8 @@
void DispSync::resetLocked() {
mPhase = 0;
- const size_t lastSampleIdx = (mFirstResyncSample + mNumResyncSamples - 1) % MAX_RESYNC_SAMPLES;
- // Keep the most recent sample, when we resync to hardware we'll overwrite this
- // with a more accurate signal
- if (mResyncSamples[lastSampleIdx] != 0) {
- mReferenceTime = mResyncSamples[lastSampleIdx];
- }
+ mReferenceTime = 0;
mModelUpdated = false;
- for (size_t i = 0; i < MAX_RESYNC_SAMPLES; i++) {
- mResyncSamples[i] = 0;
- }
mNumResyncSamples = 0;
mFirstResyncSample = 0;
mNumResyncSamplesSincePresent = 0;
@@ -547,6 +530,7 @@
Mutex::Autolock lock(mMutex);
mPeriod = period;
mPhase = 0;
+ mReferenceTime = 0;
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
}
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
index 6f3bd00..f629697 100644
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ b/services/surfaceflinger/Scheduler/DispSync.h
@@ -213,7 +213,7 @@
// These member variables are the state used during the resynchronization
// process to store information about the hardware vsync event times used
// to compute the model.
- nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES] = {0};
+ nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES];
size_t mFirstResyncSample;
size_t mNumResyncSamples;
int mNumResyncSamplesSincePresent;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 96292a8..ee033a0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1307,6 +1307,33 @@
mRegionSamplingThread->removeListener(listener);
return NO_ERROR;
}
+
+status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
+ bool* outSupport) const {
+ if (!displayToken || !outSupport) {
+ return BAD_VALUE;
+ }
+ const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+ if (!displayId) {
+ return NAME_NOT_FOUND;
+ }
+ *outSupport =
+ getHwComposer().hasDisplayCapability(displayId, HWC2::DisplayCapability::Brightness);
+ return NO_ERROR;
+}
+
+status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
+ float brightness) const {
+ if (!displayToken) {
+ return BAD_VALUE;
+ }
+ const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+ if (!displayId) {
+ return NAME_NOT_FOUND;
+ }
+ return getHwComposer().setDisplayBrightness(*displayId, brightness);
+}
+
// ----------------------------------------------------------------------------
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
@@ -3437,12 +3464,13 @@
auto& [applyToken, transactionQueue] = *it;
while (!transactionQueue.empty()) {
- const auto& [states, displays, flags, desiredPresentTime, privileged] =
+ const auto& [states, displays, flags, desiredPresentTime, postTime, privileged] =
transactionQueue.front();
if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
break;
}
- applyTransactionState(states, displays, flags, mPendingInputWindowCommands, privileged);
+ applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
+ desiredPresentTime, postTime, privileged);
transactionQueue.pop();
}
@@ -3502,6 +3530,8 @@
int64_t desiredPresentTime) {
ATRACE_CALL();
+ const int64_t postTime = systemTime();
+
bool privileged = callingThreadHasUnscopedSurfaceFlingerAccess();
Mutex::Autolock _l(mStateLock);
@@ -3514,17 +3544,19 @@
if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() ||
!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
- privileged);
+ postTime, privileged);
setTransactionFlags(eTransactionNeeded);
return;
}
- applyTransactionState(states, displays, flags, inputWindowCommands, privileged);
+ applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
+ postTime, privileged);
}
void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
+ const int64_t desiredPresentTime, const int64_t postTime,
bool privileged) {
uint32_t transactionFlags = 0;
@@ -3550,7 +3582,7 @@
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
- clientStateFlags |= setClientStateLocked(state, privileged);
+ clientStateFlags |= setClientStateLocked(state, desiredPresentTime, postTime, privileged);
}
// If the state doesn't require a traversal and there are callbacks, send them now
if (!(clientStateFlags & eTraversalNeeded)) {
@@ -3663,7 +3695,8 @@
}
uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState,
- bool privileged) {
+ int64_t desiredPresentTime, int64_t postTime,
+ bool privileged) {
const layer_state_t& s = composerState.state;
sp<Client> client(static_cast<Client*>(composerState.client.get()));
@@ -3905,7 +3938,11 @@
sp<GraphicBuffer> buffer =
BufferStateLayerCache::getInstance().get(s.cachedBuffer.token,
s.cachedBuffer.bufferId);
- if (layer->setBuffer(buffer)) flags |= eTraversalNeeded;
+ if (layer->setBuffer(buffer)) {
+ flags |= eTraversalNeeded;
+ layer->setPostTime(postTime);
+ layer->setDesiredPresentTime(desiredPresentTime);
+ }
}
if (layer->setTransactionCompletedListeners(callbackHandles)) flags |= eTraversalNeeded;
// Do not put anything that updates layer state or modifies flags after
@@ -4797,7 +4834,6 @@
case CREATE_DISPLAY:
case DESTROY_DISPLAY:
case ENABLE_VSYNC_INJECTIONS:
- case GET_ACTIVE_COLOR_MODE:
case GET_ANIMATION_FRAME_STATS:
case GET_HDR_CAPABILITIES:
case SET_ACTIVE_CONFIG:
@@ -4833,6 +4869,7 @@
// request necessary permissions. However, they do not expose any secret
// information, so it is OK to pass them.
case AUTHENTICATE_SURFACE:
+ case GET_ACTIVE_COLOR_MODE:
case GET_ACTIVE_CONFIG:
case GET_PHYSICAL_DISPLAY_IDS:
case GET_PHYSICAL_DISPLAY_TOKEN:
@@ -4848,7 +4885,9 @@
case GET_COLOR_MANAGEMENT:
case GET_COMPOSITION_PREFERENCE:
case GET_PROTECTED_CONTENT_SUPPORT:
- case IS_WIDE_COLOR_DISPLAY: {
+ case IS_WIDE_COLOR_DISPLAY:
+ case GET_DISPLAY_BRIGHTNESS_SUPPORT:
+ case SET_DISPLAY_BRIGHTNESS: {
return OK;
}
case CAPTURE_LAYERS:
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 96a21cc..42d79e1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -492,6 +492,9 @@
const std::vector<int32_t>& allowedConfigs) override;
status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
std::vector<int32_t>* outAllowedConfigs) override;
+ status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
+ bool* outSupport) const override;
+ status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const override;
/* ------------------------------------------------------------------------
* DeathRecipient interface
@@ -572,6 +575,7 @@
void applyTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
+ const int64_t desiredPresentTime, const int64_t postTime,
bool privileged) REQUIRES(mStateLock);
bool flushTransactionQueues();
uint32_t getTransactionFlags(uint32_t flags);
@@ -584,8 +588,8 @@
bool containsAnyInvalidClientState(const Vector<ComposerState>& states);
bool transactionIsReadyToBeApplied(int64_t desiredPresentTime,
const Vector<ComposerState>& states);
- uint32_t setClientStateLocked(const ComposerState& composerState, bool privileged)
- REQUIRES(mStateLock);
+ uint32_t setClientStateLocked(const ComposerState& composerState, int64_t desiredPresentTime,
+ int64_t postTime, bool privileged) REQUIRES(mStateLock);
uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock);
uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
REQUIRES(mStateLock);
@@ -1047,18 +1051,19 @@
struct TransactionState {
TransactionState(const Vector<ComposerState>& composerStates,
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
- int64_t desiredPresentTime,
- bool privileged)
+ int64_t desiredPresentTime, int64_t postTime, bool privileged)
: states(composerStates),
displays(displayStates),
flags(transactionFlags),
- time(desiredPresentTime),
+ desiredPresentTime(desiredPresentTime),
+ postTime(postTime),
privileged(privileged) {}
Vector<ComposerState> states;
Vector<DisplayState> displays;
uint32_t flags;
- int64_t time;
+ const int64_t desiredPresentTime;
+ const int64_t postTime;
bool privileged;
};
std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IBinderHash> mTransactionQueues;
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 61d09da..b667a74 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -12,7 +12,6 @@
#include <private/android_filesystem_config.h>
#include <private/gui/ComposerService.h>
-
#include <ui/DisplayInfo.h>
#include <utils/String8.h>
@@ -356,4 +355,11 @@
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
}
+TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
+ const auto display = SurfaceComposerClient::getInternalDisplayToken();
+ ASSERT_FALSE(display == nullptr);
+ ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(display);
+ ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
+}
+
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index e6f1a06..bb92020 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -121,6 +121,8 @@
MOCK_METHOD2(getDisplayCapabilities, Error(Display, std::vector<DisplayCapability>*));
MOCK_METHOD3(setLayerPerFrameMetadataBlobs,
Error(Display, Layer, const std::vector<IComposerClient::PerFrameMetadataBlob>&));
+ MOCK_METHOD2(setDisplayBrightness, Error(Display, float));
+ MOCK_METHOD2(getDisplayBrightnessSupport, Error(Display, bool*));
};
} // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index d7e20c4..6dc28bc 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -79,8 +79,9 @@
MOCK_METHOD2(validate, Error(uint32_t*, uint32_t*));
MOCK_METHOD4(presentOrValidate,
Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
+ MOCK_CONST_METHOD1(setDisplayBrightness, Error(float));
};
} // namespace mock
} // namespace Hwc2
-} // namespace android
\ No newline at end of file
+} // namespace android