Merge "SF: Make BufferData mockable"
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 8da1352..1c3a4f2 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -11,286 +11,6 @@
# Grant unix world read/write permissions to kernel tracepoints.
# Access control to these files is now entirely in selinux policy.
- chmod 0755 /sys/kernel/debug/tracing/events
- chmod 0755 /sys/kernel/debug/tracing/events/binder
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_lock
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_locked
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_set_priority
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_transaction
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_transaction_alloc_buf
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_transaction_received
- chmod 0755 /sys/kernel/debug/tracing/events/binder/binder_unlock
- chmod 0755 /sys/kernel/debug/tracing/events/block
- chmod 0755 /sys/kernel/debug/tracing/events/block/block_rq_complete
- chmod 0755 /sys/kernel/debug/tracing/events/block/block_rq_issue
- chmod 0755 /sys/kernel/debug/tracing/events/cgroup
- chmod 0755 /sys/kernel/debug/tracing/events/clk
- chmod 0755 /sys/kernel/debug/tracing/events/clk/clk_disable
- chmod 0755 /sys/kernel/debug/tracing/events/clk/clk_enable
- chmod 0755 /sys/kernel/debug/tracing/events/clk/clk_set_rate
- chmod 0755 /sys/kernel/debug/tracing/events/cpufreq_interactive
- chmod 0755 /sys/kernel/debug/tracing/events/cpuhp
- chmod 0755 /sys/kernel/debug/tracing/events/cpuhp/cpuhp_enter
- chmod 0755 /sys/kernel/debug/tracing/events/cpuhp/cpuhp_exit
- chmod 0755 /sys/kernel/debug/tracing/events/cpuhp/cpuhp_pause
- chmod 0755 /sys/kernel/debug/tracing/events/dma_fence
- chmod 0755 /sys/kernel/debug/tracing/events/ext4
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_end
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_enter
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_exit
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_load_inode
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter
- chmod 0755 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_get_data_block
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_iget
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_exit
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_begin
- chmod 0755 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_end
- chmod 0755 /sys/kernel/debug/tracing/events/fence
- chmod 0755 /sys/kernel/debug/tracing/events/filemap
- chmod 0755 /sys/kernel/debug/tracing/events/filemap/mm_filemap_add_to_page_cache
- chmod 0755 /sys/kernel/debug/tracing/events/filemap/mm_filemap_delete_from_page_cache
- chmod 0755 /sys/kernel/debug/tracing/events/gpu_mem
- chmod 0755 /sys/kernel/debug/tracing/events/gpu_mem/gpu_mem_total
- chmod 0755 /sys/kernel/debug/tracing/events/i2c
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/i2c_read
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/i2c_reply
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/i2c_result
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/i2c_write
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/smbus_read
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/smbus_reply
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/smbus_result
- chmod 0755 /sys/kernel/debug/tracing/events/i2c/smbus_write
- chmod 0755 /sys/kernel/debug/tracing/events/ion
- chmod 0755 /sys/kernel/debug/tracing/events/ion/ion_stat
- chmod 0755 /sys/kernel/debug/tracing/events/ipi
- chmod 0755 /sys/kernel/debug/tracing/events/ipi/ipi_entry
- chmod 0755 /sys/kernel/debug/tracing/events/ipi/ipi_exit
- chmod 0755 /sys/kernel/debug/tracing/events/ipi/ipi_raise
- chmod 0755 /sys/kernel/debug/tracing/events/irq
- chmod 0755 /sys/kernel/debug/tracing/events/irq/irq_handler_entry
- chmod 0755 /sys/kernel/debug/tracing/events/irq/irq_handler_exit
- chmod 0755 /sys/kernel/debug/tracing/events/irq/softirq_entry
- chmod 0755 /sys/kernel/debug/tracing/events/irq/softirq_exit
- chmod 0755 /sys/kernel/debug/tracing/events/irq/softirq_raise
- chmod 0755 /sys/kernel/debug/tracing/events/irq/tasklet_entry
- chmod 0755 /sys/kernel/debug/tracing/events/irq/tasklet_exit
- chmod 0755 /sys/kernel/debug/tracing/events/irq/tasklet_hi_entry
- chmod 0755 /sys/kernel/debug/tracing/events/irq/tasklet_hi_exit
- chmod 0755 /sys/kernel/debug/tracing/events/kmem
- chmod 0755 /sys/kernel/debug/tracing/events/kmem/ion_heap_grow
- chmod 0755 /sys/kernel/debug/tracing/events/kmem/ion_heap_shrink
- chmod 0755 /sys/kernel/debug/tracing/events/kmem/rss_stat
- chmod 0755 /sys/kernel/debug/tracing/events/lowmemorykiller
- chmod 0755 /sys/kernel/debug/tracing/events/lowmemorykiller/lowmemory_kill
- chmod 0755 /sys/kernel/debug/tracing/events/mm_event
- chmod 0755 /sys/kernel/debug/tracing/events/mm_event/mm_event_record
- chmod 0755 /sys/kernel/debug/tracing/events/oom
- chmod 0755 /sys/kernel/debug/tracing/events/oom/mark_victim
- chmod 0755 /sys/kernel/debug/tracing/events/oom/oom_score_adj_update
- chmod 0755 /sys/kernel/debug/tracing/events/power
- chmod 0755 /sys/kernel/debug/tracing/events/power/clock_disable
- chmod 0755 /sys/kernel/debug/tracing/events/power/clock_enable
- chmod 0755 /sys/kernel/debug/tracing/events/power/clock_set_rate
- chmod 0755 /sys/kernel/debug/tracing/events/power/cpu_frequency
- chmod 0755 /sys/kernel/debug/tracing/events/power/cpu_frequency_limits
- chmod 0755 /sys/kernel/debug/tracing/events/power/cpu_idle
- chmod 0755 /sys/kernel/debug/tracing/events/power/gpu_frequency
- chmod 0755 /sys/kernel/debug/tracing/events/power/suspend_resume
- chmod 0755 /sys/kernel/debug/tracing/events/sched
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_blocked_reason
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_cpu_hotplug
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_pi_setprio
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_process_exit
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_process_free
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_switch
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_wakeup
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_wakeup_new
- chmod 0755 /sys/kernel/debug/tracing/events/sched/sched_waking
- chmod 0755 /sys/kernel/debug/tracing/events/signal
- chmod 0755 /sys/kernel/debug/tracing/events/signal/signal_deliver
- chmod 0755 /sys/kernel/debug/tracing/events/signal/signal_generate
- chmod 0755 /sys/kernel/debug/tracing/events/sync
- chmod 0755 /sys/kernel/debug/tracing/events/task
- chmod 0755 /sys/kernel/debug/tracing/events/task/task_newtask
- chmod 0755 /sys/kernel/debug/tracing/events/task/task_rename
- chmod 0755 /sys/kernel/debug/tracing/events/thermal
- chmod 0755 /sys/kernel/debug/tracing/events/thermal/cdev_update
- chmod 0755 /sys/kernel/debug/tracing/events/thermal/thermal_temperature
- chmod 0755 /sys/kernel/debug/tracing/events/vmscan
- chmod 0755 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin
- chmod 0755 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end
- chmod 0755 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep
- chmod 0755 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake
- chmod 0755 /sys/kernel/debug/tracing/options
- chmod 0755 /sys/kernel/debug/tracing/per_cpu
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu0
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu1
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu2
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu3
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu4
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu5
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu6
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu7
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu8
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu9
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu10
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu11
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu12
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu13
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu14
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu15
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu16
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu17
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu18
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu19
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu20
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu21
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu22
- chmod 0755 /sys/kernel/debug/tracing/per_cpu/cpu23
- chmod 0755 /sys/kernel/tracing/events
- chmod 0755 /sys/kernel/tracing/events/binder
- chmod 0755 /sys/kernel/tracing/events/binder/binder_lock
- chmod 0755 /sys/kernel/tracing/events/binder/binder_locked
- chmod 0755 /sys/kernel/tracing/events/binder/binder_set_priority
- chmod 0755 /sys/kernel/tracing/events/binder/binder_transaction
- chmod 0755 /sys/kernel/tracing/events/binder/binder_transaction_alloc_buf
- chmod 0755 /sys/kernel/tracing/events/binder/binder_transaction_received
- chmod 0755 /sys/kernel/tracing/events/binder/binder_unlock
- chmod 0755 /sys/kernel/tracing/events/block
- chmod 0755 /sys/kernel/tracing/events/block/block_rq_complete
- chmod 0755 /sys/kernel/tracing/events/block/block_rq_issue
- chmod 0755 /sys/kernel/tracing/events/cgroup
- chmod 0755 /sys/kernel/tracing/events/clk
- chmod 0755 /sys/kernel/tracing/events/clk/clk_disable
- chmod 0755 /sys/kernel/tracing/events/clk/clk_enable
- chmod 0755 /sys/kernel/tracing/events/clk/clk_set_rate
- chmod 0755 /sys/kernel/tracing/events/cpufreq_interactive
- chmod 0755 /sys/kernel/tracing/events/cpuhp
- chmod 0755 /sys/kernel/tracing/events/cpuhp/cpuhp_enter
- chmod 0755 /sys/kernel/tracing/events/cpuhp/cpuhp_exit
- chmod 0755 /sys/kernel/tracing/events/cpuhp/cpuhp_pause
- chmod 0755 /sys/kernel/tracing/events/dma_fence
- chmod 0755 /sys/kernel/tracing/events/ext4
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_da_write_begin
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_da_write_end
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_enter
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_exit
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_load_inode
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_sync_file_enter
- chmod 0755 /sys/kernel/tracing/events/ext4/ext4_sync_file_exit
- chmod 0755 /sys/kernel/tracing/events/f2fs
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_get_data_block
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_iget
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_enter
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_exit
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_write_begin
- chmod 0755 /sys/kernel/tracing/events/f2fs/f2fs_write_end
- chmod 0755 /sys/kernel/tracing/events/fence
- chmod 0755 /sys/kernel/tracing/events/filemap
- chmod 0755 /sys/kernel/tracing/events/filemap/mm_filemap_add_to_page_cache
- chmod 0755 /sys/kernel/tracing/events/filemap/mm_filemap_delete_from_page_cache
- chmod 0755 /sys/kernel/tracing/events/gpu_mem
- chmod 0755 /sys/kernel/tracing/events/gpu_mem/gpu_mem_total
- chmod 0755 /sys/kernel/tracing/events/i2c
- chmod 0755 /sys/kernel/tracing/events/i2c/i2c_read
- chmod 0755 /sys/kernel/tracing/events/i2c/i2c_reply
- chmod 0755 /sys/kernel/tracing/events/i2c/i2c_result
- chmod 0755 /sys/kernel/tracing/events/i2c/i2c_write
- chmod 0755 /sys/kernel/tracing/events/i2c/smbus_read
- chmod 0755 /sys/kernel/tracing/events/i2c/smbus_reply
- chmod 0755 /sys/kernel/tracing/events/i2c/smbus_result
- chmod 0755 /sys/kernel/tracing/events/i2c/smbus_write
- chmod 0755 /sys/kernel/tracing/events/ion
- chmod 0755 /sys/kernel/tracing/events/ion/ion_stat
- chmod 0755 /sys/kernel/tracing/events/ipi
- chmod 0755 /sys/kernel/tracing/events/ipi/ipi_entry
- chmod 0755 /sys/kernel/tracing/events/ipi/ipi_exit
- chmod 0755 /sys/kernel/tracing/events/ipi/ipi_raise
- chmod 0755 /sys/kernel/tracing/events/irq
- chmod 0755 /sys/kernel/tracing/events/irq/irq_handler_entry
- chmod 0755 /sys/kernel/tracing/events/irq/irq_handler_exit
- chmod 0755 /sys/kernel/tracing/events/irq/softirq_entry
- chmod 0755 /sys/kernel/tracing/events/irq/softirq_exit
- chmod 0755 /sys/kernel/tracing/events/irq/softirq_raise
- chmod 0755 /sys/kernel/tracing/events/irq/tasklet_entry
- chmod 0755 /sys/kernel/tracing/events/irq/tasklet_exit
- chmod 0755 /sys/kernel/tracing/events/irq/tasklet_hi_entry
- chmod 0755 /sys/kernel/tracing/events/irq/tasklet_hi_exit
- chmod 0755 /sys/kernel/tracing/events/kmem
- chmod 0755 /sys/kernel/tracing/events/kmem/ion_heap_grow
- chmod 0755 /sys/kernel/tracing/events/kmem/ion_heap_shrink
- chmod 0755 /sys/kernel/tracing/events/kmem/rss_stat
- chmod 0755 /sys/kernel/tracing/events/lowmemorykiller
- chmod 0755 /sys/kernel/tracing/events/lowmemorykiller/lowmemory_kill
- chmod 0755 /sys/kernel/tracing/events/mm_event
- chmod 0755 /sys/kernel/tracing/events/mm_event/mm_event_record
- chmod 0755 /sys/kernel/tracing/events/oom
- chmod 0755 /sys/kernel/tracing/events/oom/mark_victim
- chmod 0755 /sys/kernel/tracing/events/oom/oom_score_adj_update
- chmod 0755 /sys/kernel/tracing/events/power
- chmod 0755 /sys/kernel/tracing/events/power/clock_disable
- chmod 0755 /sys/kernel/tracing/events/power/clock_enable
- chmod 0755 /sys/kernel/tracing/events/power/clock_set_rate
- chmod 0755 /sys/kernel/tracing/events/power/cpu_frequency
- chmod 0755 /sys/kernel/tracing/events/power/cpu_frequency_limits
- chmod 0755 /sys/kernel/tracing/events/power/cpu_idle
- chmod 0755 /sys/kernel/tracing/events/power/gpu_frequency
- chmod 0755 /sys/kernel/tracing/events/power/suspend_resume
- chmod 0755 /sys/kernel/tracing/events/sched
- chmod 0755 /sys/kernel/tracing/events/sched/sched_blocked_reason
- chmod 0755 /sys/kernel/tracing/events/sched/sched_cpu_hotplug
- chmod 0755 /sys/kernel/tracing/events/sched/sched_pi_setprio
- chmod 0755 /sys/kernel/tracing/events/sched/sched_process_exit
- chmod 0755 /sys/kernel/tracing/events/sched/sched_process_free
- chmod 0755 /sys/kernel/tracing/events/sched/sched_switch
- chmod 0755 /sys/kernel/tracing/events/sched/sched_wakeup
- chmod 0755 /sys/kernel/tracing/events/sched/sched_wakeup_new
- chmod 0755 /sys/kernel/tracing/events/sched/sched_waking
- chmod 0755 /sys/kernel/tracing/events/signal
- chmod 0755 /sys/kernel/tracing/events/signal/signal_deliver
- chmod 0755 /sys/kernel/tracing/events/signal/signal_generate
- chmod 0755 /sys/kernel/tracing/events/sync
- chmod 0755 /sys/kernel/tracing/events/task
- chmod 0755 /sys/kernel/tracing/events/task/task_newtask
- chmod 0755 /sys/kernel/tracing/events/task/task_rename
- chmod 0755 /sys/kernel/tracing/events/thermal
- chmod 0755 /sys/kernel/tracing/events/thermal/cdev_update
- chmod 0755 /sys/kernel/tracing/events/thermal/thermal_temperature
- chmod 0755 /sys/kernel/tracing/events/vmscan
- chmod 0755 /sys/kernel/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin
- chmod 0755 /sys/kernel/tracing/events/vmscan/mm_vmscan_direct_reclaim_end
- chmod 0755 /sys/kernel/tracing/events/vmscan/mm_vmscan_kswapd_sleep
- chmod 0755 /sys/kernel/tracing/events/vmscan/mm_vmscan_kswapd_wake
- chmod 0755 /sys/kernel/tracing/options
- chmod 0755 /sys/kernel/tracing/per_cpu
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu0
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu1
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu2
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu3
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu4
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu5
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu6
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu7
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu8
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu9
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu10
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu11
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu12
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu13
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu14
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu15
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu16
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu17
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu18
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu19
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu20
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu21
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu22
- chmod 0755 /sys/kernel/tracing/per_cpu/cpu23
chmod 0666 /sys/kernel/debug/tracing/trace_clock
chmod 0666 /sys/kernel/tracing/trace_clock
chmod 0666 /sys/kernel/debug/tracing/buffer_size_kb
@@ -315,6 +35,8 @@
chmod 0666 /sys/kernel/tracing/events/sched/sched_pi_setprio/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_process_exit/enable
chmod 0666 /sys/kernel/tracing/events/sched/sched_process_exit/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_process_free/enable
+ chmod 0666 /sys/kernel/tracing/events/sched/sched_process_free/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_waking/enable
chmod 0666 /sys/kernel/tracing/events/sched/sched_waking/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_wakeup_new/enable
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 32e680d..e97949e 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1802,8 +1802,8 @@
// Add linker configuration directory
ds.AddDir(LINKERCONFIG_DIR, true);
- /* Dump cgroupfs */
- ds.AddDir(CGROUPFS_DIR, true);
+ /* Dump frozen cgroupfs */
+ dump_frozen_cgroupfs();
if (ds.dump_pool_) {
WAIT_TASK_WITH_CONSENT_CHECK(DUMP_INCIDENT_REPORT_TASK, ds.dump_pool_);
@@ -4169,6 +4169,63 @@
fclose(fp);
}
+void dump_frozen_cgroupfs(const char *dir, int level,
+ int (*dump_from_fd)(const char* title, const char* path, int fd)) {
+ DIR *dirp;
+ struct dirent *d;
+ char *newpath = nullptr;
+
+ dirp = opendir(dir);
+ if (dirp == nullptr) {
+ MYLOGE("%s: %s\n", dir, strerror(errno));
+ return;
+ }
+
+ for (; ((d = readdir(dirp))); free(newpath), newpath = nullptr) {
+ if ((d->d_name[0] == '.')
+ && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
+ || (d->d_name[1] == '\0'))) {
+ continue;
+ }
+ if (d->d_type == DT_DIR) {
+ asprintf(&newpath, "%s/%s/", dir, d->d_name);
+ if (!newpath) {
+ continue;
+ }
+ if (level == 0 && !strncmp(d->d_name, "uid_", 4)) {
+ dump_frozen_cgroupfs(newpath, 1, dump_from_fd);
+ } else if (level == 1 && !strncmp(d->d_name, "pid_", 4)) {
+ char *freezer = nullptr;
+ asprintf(&freezer, "%s/%s", newpath, "cgroup.freeze");
+ if (freezer) {
+ FILE* fp = fopen(freezer, "r");
+ if (fp != NULL) {
+ int frozen;
+ fscanf(fp, "%d", &frozen);
+ if (frozen > 0) {
+ dump_files("", newpath, skip_none, dump_from_fd);
+ }
+ fclose(fp);
+ }
+ free(freezer);
+ }
+ }
+ }
+ }
+ closedir(dirp);
+}
+
+void dump_frozen_cgroupfs() {
+ if (!ds.IsZipping()) {
+ MYLOGD("Not adding cgroupfs because it's not a zipped bugreport\n");
+ return;
+ }
+ MYLOGD("Adding frozen processes from %s\n", CGROUPFS_DIR);
+ DurationReporter duration_reporter("FROZEN CGROUPFS");
+ if (PropertiesHelper::IsDryRun()) return;
+ dump_frozen_cgroupfs(CGROUPFS_DIR, 0, _add_file_from_fd);
+}
+
void Dumpstate::UpdateProgress(int32_t delta_sec) {
if (progress_ == nullptr) {
MYLOGE("UpdateProgress: progress_ not set\n");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 773e292..852b9a8 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -637,6 +637,9 @@
/* Prints the contents of all the routing tables, both IPv4 and IPv6. */
void dump_route_tables();
+/* Dump subdirectories of cgroupfs if the corresponding process is frozen */
+void dump_frozen_cgroupfs();
+
/* Play a sound via Stagefright */
void play_sound(const char *path);
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index bdc6127..dd96683 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -190,13 +190,15 @@
SurfaceComposerClient::Transaction t;
const bool surfaceControlChanged = !SurfaceControl::isSameSurface(mSurfaceControl, surface);
+ if (surfaceControlChanged && mSurfaceControl != nullptr) {
+ BQA_LOGD("Updating SurfaceControl without recreating BBQ");
+ }
bool applyTransaction = false;
// Always update the native object even though they might have the same layer handle, so we can
// get the updated transform hint from WM.
mSurfaceControl = surface;
if (surfaceControlChanged) {
- BQA_LOGD("Updating SurfaceControl without recreating BBQ");
t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure);
applyTransaction = true;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 068e03c..2c5b321 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2330,6 +2330,17 @@
mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
}
+ void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
+ EXPECT_EQ(action, args.action);
+ ASSERT_EQ(points.size(), args.pointerCount);
+ for (size_t i = 0; i < args.pointerCount; i++) {
+ EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
+ EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
+ }
+ }
+
std::unique_ptr<UinputTouchScreen> mDevice;
};
@@ -2340,16 +2351,19 @@
// ACTION_DOWN
mDevice->sendTrackingId(FIRST_TRACKING_ID);
mDevice->sendDown(centerPoint);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
// ACTION_MOVE
mDevice->sendMove(centerPoint + Point(1, 1));
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
// ACTION_UP
mDevice->sendUp();
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
}
@@ -2362,6 +2376,7 @@
mDevice->sendSlot(FIRST_SLOT);
mDevice->sendTrackingId(FIRST_TRACKING_ID);
mDevice->sendDown(centerPoint);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
@@ -2369,27 +2384,129 @@
const Point secondPoint = centerPoint + Point(100, 100);
mDevice->sendSlot(SECOND_SLOT);
mDevice->sendTrackingId(SECOND_TRACKING_ID);
- mDevice->sendDown(secondPoint + Point(1, 1));
+ mDevice->sendDown(secondPoint);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
// ACTION_MOVE (Second slot)
- mDevice->sendMove(secondPoint);
+ mDevice->sendMove(secondPoint + Point(1, 1));
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
// ACTION_POINTER_UP (Second slot)
mDevice->sendPointerUp();
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
// ACTION_UP
mDevice->sendSlot(FIRST_SLOT);
mDevice->sendUp();
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
}
+/**
+ * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
+ * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
+ * data?
+ * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
+ * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
+ * for Pointer 0 only is generated after.
+ * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
+ * events, we will not miss any information.
+ * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
+ * event generated afterwards that contains the newest movement of pointer 0.
+ * This is important for palm rejection. If there is a subsequent InputListener stage that detects
+ * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
+ * losing information about non-palm pointers.
+ */
+TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
+ NotifyMotionArgs args;
+ const Point centerPoint = mDevice->getCenterPoint();
+
+ // ACTION_DOWN
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendTrackingId(FIRST_TRACKING_ID);
+ mDevice->sendDown(centerPoint);
+ mDevice->sendSync();
+ assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
+
+ // ACTION_POINTER_DOWN (Second slot)
+ const Point secondPoint = centerPoint + Point(100, 100);
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendTrackingId(SECOND_TRACKING_ID);
+ mDevice->sendDown(secondPoint);
+ mDevice->sendSync();
+ assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
+
+ // ACTION_MOVE (First slot)
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendMove(centerPoint + Point(5, 5));
+ // ACTION_POINTER_UP (Second slot)
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendPointerUp();
+ // Send a single sync for the above 2 pointer updates
+ mDevice->sendSync();
+
+ // First, we should get POINTER_UP for the second pointer
+ assertReceivedMotion(ACTION_POINTER_1_UP,
+ {/*first pointer */ centerPoint + Point(5, 5),
+ /*second pointer*/ secondPoint});
+
+ // Next, the MOVE event for the first pointer
+ assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
+}
+
+/**
+ * Similar scenario as above. The difference is that when the second pointer goes up, it will first
+ * move, and then it will go up, all in the same frame.
+ * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
+ * gets sent to the listener.
+ */
+TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
+ NotifyMotionArgs args;
+ const Point centerPoint = mDevice->getCenterPoint();
+
+ // ACTION_DOWN
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendTrackingId(FIRST_TRACKING_ID);
+ mDevice->sendDown(centerPoint);
+ mDevice->sendSync();
+ assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
+
+ // ACTION_POINTER_DOWN (Second slot)
+ const Point secondPoint = centerPoint + Point(100, 100);
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendTrackingId(SECOND_TRACKING_ID);
+ mDevice->sendDown(secondPoint);
+ mDevice->sendSync();
+ assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
+
+ // ACTION_MOVE (First slot)
+ mDevice->sendSlot(FIRST_SLOT);
+ mDevice->sendMove(centerPoint + Point(5, 5));
+ // ACTION_POINTER_UP (Second slot)
+ mDevice->sendSlot(SECOND_SLOT);
+ mDevice->sendMove(secondPoint + Point(6, 6));
+ mDevice->sendPointerUp();
+ // Send a single sync for the above 2 pointer updates
+ mDevice->sendSync();
+
+ // First, we should get POINTER_UP for the second pointer
+ // The movement of the second pointer during the liftoff frame is ignored.
+ // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
+ assertReceivedMotion(ACTION_POINTER_1_UP,
+ {/*first pointer */ centerPoint + Point(5, 5),
+ /*second pointer*/ secondPoint});
+
+ // Next, the MOVE event for the first pointer
+ assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
+}
+
TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
NotifyMotionArgs args;
const Point centerPoint = mDevice->getCenterPoint();
@@ -2398,6 +2515,7 @@
mDevice->sendSlot(FIRST_SLOT);
mDevice->sendTrackingId(FIRST_TRACKING_ID);
mDevice->sendDown(centerPoint);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
@@ -2406,11 +2524,13 @@
mDevice->sendSlot(SECOND_SLOT);
mDevice->sendTrackingId(SECOND_TRACKING_ID);
mDevice->sendDown(secondPoint);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
// ACTION_MOVE (second slot)
mDevice->sendMove(secondPoint + Point(1, 1));
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
@@ -2418,18 +2538,21 @@
// a palm event.
// Expect to receive the ACTION_POINTER_UP with cancel flag.
mDevice->sendToolType(MT_TOOL_PALM);
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
// Send up to second slot, expect first slot send moving.
mDevice->sendPointerUp();
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
// Send ACTION_UP (first slot)
mDevice->sendSlot(FIRST_SLOT);
mDevice->sendUp();
+ mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
diff --git a/services/inputflinger/tests/UinputDevice.cpp b/services/inputflinger/tests/UinputDevice.cpp
index 7fec2c8..132b877 100644
--- a/services/inputflinger/tests/UinputDevice.cpp
+++ b/services/inputflinger/tests/UinputDevice.cpp
@@ -170,28 +170,27 @@
injectEvent(EV_KEY, BTN_TOUCH, 1);
injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
- injectEvent(EV_SYN, SYN_REPORT, 0);
}
void UinputTouchScreen::sendMove(const Point& point) {
injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
- injectEvent(EV_SYN, SYN_REPORT, 0);
}
void UinputTouchScreen::sendPointerUp() {
sendTrackingId(0xffffffff);
- injectEvent(EV_SYN, SYN_REPORT, 0);
}
void UinputTouchScreen::sendUp() {
sendTrackingId(0xffffffff);
injectEvent(EV_KEY, BTN_TOUCH, 0);
- injectEvent(EV_SYN, SYN_REPORT, 0);
}
void UinputTouchScreen::sendToolType(int32_t toolType) {
injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType);
+}
+
+void UinputTouchScreen::sendSync() {
injectEvent(EV_SYN, SYN_REPORT, 0);
}
diff --git a/services/inputflinger/tests/UinputDevice.h b/services/inputflinger/tests/UinputDevice.h
index 01a557c..a37fc2b 100644
--- a/services/inputflinger/tests/UinputDevice.h
+++ b/services/inputflinger/tests/UinputDevice.h
@@ -142,6 +142,7 @@
void sendPointerUp();
void sendUp();
void sendToolType(int32_t toolType);
+ void sendSync();
const Point getCenterPoint();
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp
index b907478..049d06a 100644
--- a/services/sensorservice/AidlSensorHalWrapper.cpp
+++ b/services/sensorservice/AidlSensorHalWrapper.cpp
@@ -252,6 +252,7 @@
*dst = {
.timestamp = src.timestamp,
.sensorHandle = src.sensor,
+ .sensorType = (SensorType) src.type,
};
switch (dst->sensorType) {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 73770b7..6cb12dd 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -173,6 +173,8 @@
// Sets the projection state to use
virtual void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
const Rect& orientedDisplaySpaceRect) = 0;
+ // Sets the brightness that will take effect next frame.
+ virtual void setNextBrightness(float brightness) = 0;
// Sets the bounds to use
virtual void setDisplaySize(const ui::Size&) = 0;
// Gets the transform hint used in layers that belong to this output. Used to guide
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 844876a..a7a8e97 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -45,6 +45,7 @@
void setLayerCachingTexturePoolEnabled(bool) override;
void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
const Rect& orientedDisplaySpaceRect) override;
+ void setNextBrightness(float brightness) override;
void setDisplaySize(const ui::Size&) override;
void setLayerFilter(ui::LayerFilter) override;
ui::Transform::RotationFlags getTransformHint() const override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index c8f177b..cc7c257 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -133,6 +133,10 @@
// White point of the client target
float clientTargetWhitePointNits{-1.f};
+ // Display brightness that will take effect this frame.
+ // This is slightly distinct from nits, in that nits cannot be passed to hw composer.
+ std::optional<float> displayBrightness = std::nullopt;
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 7b0d028..b68b95d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -39,6 +39,7 @@
MOCK_METHOD1(setLayerCachingEnabled, void(bool));
MOCK_METHOD1(setLayerCachingTexturePoolEnabled, void(bool));
MOCK_METHOD3(setProjection, void(ui::Rotation, const Rect&, const Rect&));
+ MOCK_METHOD1(setNextBrightness, void(float));
MOCK_METHOD1(setDisplaySize, void(const ui::Size&));
MOCK_CONST_METHOD0(getTransformHint, ui::Transform::RotationFlags());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 08dd22d..186e191 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -226,6 +226,17 @@
// Get any composition changes requested by the HWC device, and apply them.
std::optional<android::HWComposer::DeviceRequestedChanges> changes;
auto& hwc = getCompositionEngine().getHwComposer();
+ if (const auto physicalDisplayId = PhysicalDisplayId::tryCast(*halDisplayId);
+ physicalDisplayId && getState().displayBrightness) {
+ const status_t result =
+ hwc.setDisplayBrightness(*physicalDisplayId, *getState().displayBrightness,
+ Hwc2::Composer::DisplayBrightnessOptions{
+ .applyImmediately = false})
+ .get();
+ ALOGE_IF(result != NO_ERROR, "setDisplayBrightness failed for %s: %d, (%s)",
+ getName().c_str(), result, strerror(-result));
+ }
+
if (status_t result =
hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
getState().earliestPresentTime,
@@ -248,6 +259,8 @@
auto& state = editState();
state.usesClientComposition = anyLayersRequireClientComposition();
state.usesDeviceComposition = !allLayersRequireClientComposition();
+ // Clear out the display brightness now that it's been communicated to composer.
+ state.displayBrightness.reset();
}
bool Display::getSkipColorTransform() const {
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 6833584..192ee04 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -197,6 +197,10 @@
dirtyEntireOutput();
}
+void Output::setNextBrightness(float brightness) {
+ editState().displayBrightness = brightness;
+}
+
void Output::setDisplaySize(const ui::Size& size) {
mRenderSurface->setDisplaySize(size);
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 545e2a2..95cc5a8 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -481,7 +481,7 @@
if (auto error = hwcLayer->setVisibleRegion(visibleRegion); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
- outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG);
+ visibleRegion.dump(LOG_TAG);
}
const auto dataspace = outputDependentState.overrideInfo.buffer
@@ -551,10 +551,10 @@
void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState) {
- hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
- static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
- static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),
- 255};
+ aidl::android::hardware::graphics::composer3::Color color = {outputIndependentState.color.r,
+ outputIndependentState.color.g,
+ outputIndependentState.color.b,
+ 1.0f};
if (auto error = hwcLayer->setColor(color); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set color: %s (%d)", getLayerFE().getDebugName(),
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 8558a80..7dd4c21 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -37,6 +37,7 @@
#include "MockHWC2.h"
#include "MockHWComposer.h"
#include "MockPowerAdvisor.h"
+#include "ftl/future.h"
#include <aidl/android/hardware/graphics/composer3/Composition.h>
@@ -48,6 +49,7 @@
namespace hal = android::hardware::graphics::composer::hal;
using testing::_;
+using testing::ByMove;
using testing::DoAll;
using testing::Eq;
using testing::InSequence;
@@ -594,6 +596,38 @@
EXPECT_TRUE(state.usesDeviceComposition);
}
+TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithDisplayBrightness) {
+ // Since two calls are made to anyLayersRequireClientComposition with different return
+ // values, use a Sequence to control the matching so the values are returned in a known
+ // order.
+ constexpr float kDisplayBrightness = 0.5f;
+ Sequence s;
+ EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition())
+ .InSequence(s)
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition())
+ .InSequence(s)
+ .WillOnce(Return(false));
+ EXPECT_CALL(mHwComposer,
+ setDisplayBrightness(DEFAULT_DISPLAY_ID, kDisplayBrightness,
+ Hwc2::Composer::DisplayBrightnessOptions{.applyImmediately =
+ false}))
+ .WillOnce(Return(ByMove(ftl::yield<status_t>(NO_ERROR))));
+
+ EXPECT_CALL(mHwComposer,
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _, _))
+ .WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
+
+ mDisplay->setNextBrightness(kDisplayBrightness);
+ mDisplay->chooseCompositionStrategy();
+
+ auto& state = mDisplay->getState();
+ EXPECT_FALSE(state.usesClientComposition);
+ EXPECT_TRUE(state.usesDeviceComposition);
+ EXPECT_FALSE(state.displayBrightness.has_value());
+}
+
TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
android::HWComposer::DeviceRequestedChanges changes{
{{nullptr, Composition::CLIENT}},
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
index ff68053..5185ea9 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
@@ -58,7 +58,7 @@
const android::sp<android::Fence>&));
MOCK_METHOD1(setSurfaceDamage, Error(const android::Region&));
MOCK_METHOD1(setBlendMode, Error(hal::BlendMode));
- MOCK_METHOD1(setColor, Error(hal::Color));
+ MOCK_METHOD1(setColor, Error(aidl::android::hardware::graphics::composer3::Color));
MOCK_METHOD1(setCompositionType,
Error(aidl::android::hardware::graphics::composer3::Composition));
MOCK_METHOD1(setDataspace, Error(android::ui::Dataspace));
@@ -75,6 +75,7 @@
MOCK_METHOD3(setLayerGenericMetadata,
Error(const std::string&, bool, const std::vector<uint8_t>&));
MOCK_METHOD1(setWhitePointNits, Error(float));
+ MOCK_METHOD1(setBlockingRegion, Error(const android::Region&));
};
} // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index a590e2a..dc5c5c8 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -83,7 +83,9 @@
MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(HalDisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
status_t(HalDisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
- MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(PhysicalDisplayId, float));
+ MOCK_METHOD3(setDisplayBrightness,
+ std::future<status_t>(PhysicalDisplayId, float,
+ const Hwc2::Composer::DisplayBrightnessOptions&));
MOCK_METHOD2(getDisplayBrightnessSupport, status_t(PhysicalDisplayId, bool*));
MOCK_METHOD2(onHotplug,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index ad7976f..f34b621 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -864,9 +864,8 @@
}
void expectSetColorCall() {
- const hal::Color color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
- static_cast<uint8_t>(std::round(kColor.g * 255)),
- static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
+ const aidl::android::hardware::graphics::composer3::Color color = {kColor.r, kColor.g,
+ kColor.b, 1.0f};
EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 6d96260..f7c7533 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -574,6 +574,17 @@
EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
}
+/**
+ * Output::setDisplayBrightness()
+ */
+
+TEST_F(OutputTest, setNextBrightness) {
+ constexpr float kDisplayBrightness = 0.5f;
+ mOutput->setNextBrightness(kDisplayBrightness);
+ ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
+ EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
+}
+
/*
* Output::getDirtyRegion()
*/
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 76bbe2c..a36ea72 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -311,6 +311,22 @@
orientedDisplaySpaceRect);
}
+void DisplayDevice::stageBrightness(float brightness) {
+ mStagedBrightness = brightness;
+}
+
+void DisplayDevice::persistBrightness(bool needsComposite) {
+ if (needsComposite && mStagedBrightness && mBrightness != *mStagedBrightness) {
+ getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
+ mBrightness = *mStagedBrightness;
+ }
+ mStagedBrightness = std::nullopt;
+}
+
+std::optional<float> DisplayDevice::getStagedBrightness() const {
+ return mStagedBrightness;
+}
+
ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() {
return sPrimaryDisplayRotationFlags;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 324145e..d2accaa 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -99,6 +99,9 @@
void setLayerStack(ui::LayerStack);
void setDisplaySize(int width, int height);
void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
+ void stageBrightness(float brightness) REQUIRES(SF_MAIN_THREAD);
+ void persistBrightness(bool needsComposite) REQUIRES(SF_MAIN_THREAD);
+ bool isBrightnessStale() const REQUIRES(SF_MAIN_THREAD);
void setFlags(uint32_t flags);
ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; }
@@ -106,6 +109,7 @@
static ui::Transform::RotationFlags getPrimaryDisplayRotationFlags();
+ std::optional<float> getStagedBrightness() const REQUIRES(SF_MAIN_THREAD);
ui::Transform::RotationFlags getTransformHint() const;
const ui::Transform& getTransform() const;
const Rect& getLayerStackSpaceRect() const;
@@ -271,6 +275,8 @@
hardware::graphics::composer::hal::PowerMode mPowerMode =
hardware::graphics::composer::hal::PowerMode::OFF;
DisplayModePtr mActiveMode;
+ std::optional<float> mStagedBrightness = std::nullopt;
+ float mBrightness = -1.f;
const DisplayModes mSupportedModes;
std::atomic<nsecs_t> mLastHwVsync = 0;
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 1091a75..3c578bc 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -110,16 +110,6 @@
}
template <>
-Color translate(IComposerClient::Color x) {
- return Color{
- .r = static_cast<int8_t>(x.r),
- .g = static_cast<int8_t>(x.g),
- .b = static_cast<int8_t>(x.b),
- .a = static_cast<int8_t>(x.a),
- };
-}
-
-template <>
AidlPerFrameMetadataBlob translate(IComposerClient::PerFrameMetadataBlob x) {
AidlPerFrameMetadataBlob blob;
blob.key = translate<AidlPerFrameMetadataKey>(x.key),
@@ -246,6 +236,7 @@
switch (feature) {
case OptionalFeature::RefreshRateSwitching:
case OptionalFeature::ExpectedPresentTime:
+ case OptionalFeature::DisplayBrightnessCommand:
return true;
}
}
@@ -669,10 +660,8 @@
return Error::NONE;
}
-Error AidlComposer::setLayerColor(Display display, Layer layer,
- const IComposerClient::Color& color) {
- mWriter.setLayerColor(translate<int64_t>(display), translate<int64_t>(layer),
- translate<Color>(color));
+Error AidlComposer::setLayerColor(Display display, Layer layer, const Color& color) {
+ mWriter.setLayerColor(translate<int64_t>(display), translate<int64_t>(layer), color);
return Error::NONE;
}
@@ -906,13 +895,14 @@
return Error::NONE;
}
-Error AidlComposer::setDisplayBrightness(Display display, float brightness) {
- const auto status =
- mAidlComposerClient->setDisplayBrightness(translate<int64_t>(display), brightness);
- if (!status.isOk()) {
- ALOGE("setDisplayBrightness failed %s", status.getDescription().c_str());
- return static_cast<Error>(status.getServiceSpecificError());
+Error AidlComposer::setDisplayBrightness(Display display, float brightness,
+ const DisplayBrightnessOptions& options) {
+ mWriter.setDisplayBrightness(translate<int64_t>(display), brightness);
+
+ if (options.applyImmediately) {
+ return execute();
}
+
return Error::NONE;
}
@@ -1035,5 +1025,11 @@
return Error::NONE;
}
+Error AidlComposer::setLayerBlockingRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& blocking) {
+ mWriter.setLayerBlockingRegion(translate<int64_t>(display), translate<int64_t>(layer),
+ translate<AidlRect>(blocking));
+ return Error::NONE;
+}
} // namespace Hwc2
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 5c41982..cdd16e2 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -139,7 +139,7 @@
Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& damage) override;
Error setLayerBlendMode(Display display, Layer layer, IComposerClient::BlendMode mode) override;
- Error setLayerColor(Display display, Layer layer, const IComposerClient::Color& color) override;
+ Error setLayerColor(Display display, Layer layer, const Color& color) override;
Error setLayerCompositionType(
Display display, Layer layer,
aidl::android::hardware::graphics::composer3::Composition type) override;
@@ -180,7 +180,8 @@
Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override;
- Error setDisplayBrightness(Display display, float brightness) override;
+ Error setDisplayBrightness(Display display, float brightness,
+ const DisplayBrightnessOptions& options) override;
// Composer HAL 2.4
Error getDisplayCapabilities(
@@ -207,7 +208,11 @@
Error getClientTargetProperty(Display display,
IComposerClient::ClientTargetProperty* outClientTargetProperty,
float* outClientTargetWhitePointNits) override;
+
+ // AIDL Composer HAL
Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
+ Error setLayerBlockingRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& blocking) override;
private:
// Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index f491a00..bb4b784 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -31,6 +31,7 @@
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
+#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -78,6 +79,8 @@
enum class OptionalFeature {
RefreshRateSwitching,
ExpectedPresentTime,
+ // Whether setDisplayBrightness is able to be applied as part of a display command.
+ DisplayBrightnessCommand,
};
virtual bool isSupported(OptionalFeature) const = 0;
@@ -162,8 +165,9 @@
const std::vector<IComposerClient::Rect>& damage) = 0;
virtual Error setLayerBlendMode(Display display, Layer layer,
IComposerClient::BlendMode mode) = 0;
- virtual Error setLayerColor(Display display, Layer layer,
- const IComposerClient::Color& color) = 0;
+ virtual Error setLayerColor(
+ Display display, Layer layer,
+ const aidl::android::hardware::graphics::composer3::Color& color) = 0;
virtual Error setLayerCompositionType(
Display display, Layer layer,
aidl::android::hardware::graphics::composer3::Composition type) = 0;
@@ -204,7 +208,20 @@
DisplayedFrameStats* outStats) = 0;
virtual Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer, const std::vector<PerFrameMetadataBlob>& metadata) = 0;
- virtual Error setDisplayBrightness(Display display, float brightness) = 0;
+ // Options for setting the display brightness
+ struct DisplayBrightnessOptions {
+ // If true, then immediately submits a brightness change request to composer. Otherwise,
+ // submission of the brightness change may be deferred until presenting the next frame.
+ // applyImmediately should only be false if OptionalFeature::DisplayBrightnessCommand is
+ // supported.
+ bool applyImmediately = true;
+
+ bool operator==(const DisplayBrightnessOptions& other) const {
+ return applyImmediately == other.applyImmediately;
+ }
+ };
+ virtual Error setDisplayBrightness(Display display, float brightness,
+ const DisplayBrightnessOptions& options) = 0;
// Composer HAL 2.4
virtual Error getDisplayCapabilities(
@@ -237,6 +254,8 @@
// AIDL Composer
virtual Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) = 0;
+ virtual Error setLayerBlockingRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& blocking) = 0;
};
} // namespace android::Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 548d839..34f2e76 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -37,8 +37,7 @@
#include <iterator>
#include <set>
-#include "ComposerHal.h"
-
+using aidl::android::hardware::graphics::composer3::Color;
using aidl::android::hardware::graphics::composer3::Composition;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
@@ -532,9 +531,10 @@
return error;
}
-std::future<Error> Display::setDisplayBrightness(float brightness) {
- return ftl::defer([composer = &mComposer, id = mId, brightness] {
- const auto intError = composer->setDisplayBrightness(id, brightness);
+std::future<Error> Display::setDisplayBrightness(
+ float brightness, const Hwc2::Composer::DisplayBrightnessOptions& options) {
+ return ftl::defer([composer = &mComposer, id = mId, brightness, options] {
+ const auto intError = composer->setDisplayBrightness(id, brightness, options);
return static_cast<Error>(intError);
});
}
@@ -584,6 +584,21 @@
// Layer methods
+namespace {
+std::vector<Hwc2::IComposerClient::Rect> convertRegionToHwcRects(const Region& region) {
+ size_t rectCount = 0;
+ Rect const* rectArray = region.getArray(&rectCount);
+
+ std::vector<Hwc2::IComposerClient::Rect> hwcRects;
+ hwcRects.reserve(rectCount);
+ for (size_t rect = 0; rect < rectCount; ++rect) {
+ hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, rectArray[rect].right,
+ rectArray[rect].bottom});
+ }
+ return hwcRects;
+}
+} // namespace
+
Layer::~Layer() = default;
namespace impl {
@@ -674,15 +689,7 @@
intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId,
std::vector<Hwc2::IComposerClient::Rect>());
} else {
- size_t rectCount = 0;
- auto rectArray = damage.getArray(&rectCount);
-
- std::vector<Hwc2::IComposerClient::Rect> hwcRects;
- for (size_t rect = 0; rect < rectCount; ++rect) {
- hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
- rectArray[rect].right, rectArray[rect].bottom});
- }
-
+ const auto hwcRects = convertRegionToHwcRects(damage);
intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId, hwcRects);
}
@@ -870,16 +877,7 @@
return Error::NONE;
}
mVisibleRegion = region;
-
- size_t rectCount = 0;
- auto rectArray = region.getArray(&rectCount);
-
- std::vector<Hwc2::IComposerClient::Rect> hwcRects;
- for (size_t rect = 0; rect < rectCount; ++rect) {
- hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
- rectArray[rect].right, rectArray[rect].bottom});
- }
-
+ const auto hwcRects = convertRegionToHwcRects(region);
auto intError = mComposer.setLayerVisibleRegion(mDisplay->getId(), mId, hwcRects);
return static_cast<Error>(intError);
}
@@ -934,6 +932,21 @@
return static_cast<Error>(intError);
}
+Error Layer::setBlockingRegion(const Region& region) {
+ if (CC_UNLIKELY(!mDisplay)) {
+ return Error::BAD_DISPLAY;
+ }
+
+ if (region.isRect() && mBlockingRegion.isRect() &&
+ (region.getBounds() == mBlockingRegion.getBounds())) {
+ return Error::NONE;
+ }
+ mBlockingRegion = region;
+ const auto hwcRects = convertRegionToHwcRects(region);
+ const auto intError = mComposer.setLayerBlockingRegion(mDisplay->getId(), mId, hwcRects);
+ return static_cast<Error>(intError);
+}
+
} // namespace impl
} // namespace HWC2
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 731d7f6..01a482d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -34,8 +34,10 @@
#include <unordered_set>
#include <vector>
+#include "ComposerHal.h"
#include "Hal.h"
+#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -143,7 +145,7 @@
nsecs_t expectedPresentTime, uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
[[clang::warn_unused_result]] virtual std::future<hal::Error> setDisplayBrightness(
- float brightness) = 0;
+ float brightness, const Hwc2::Composer::DisplayBrightnessOptions& options) = 0;
[[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
hal::HWConfigId configId, const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
@@ -211,7 +213,8 @@
uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence,
uint32_t* state) override;
- std::future<hal::Error> setDisplayBrightness(float brightness) override;
+ std::future<hal::Error> setDisplayBrightness(
+ float brightness, const Hwc2::Composer::DisplayBrightnessOptions& options) override;
hal::Error setActiveConfigWithConstraints(hal::HWConfigId configId,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
@@ -277,7 +280,8 @@
const android::Region& damage) = 0;
[[clang::warn_unused_result]] virtual hal::Error setBlendMode(hal::BlendMode mode) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setColor(hal::Color color) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setColor(
+ aidl::android::hardware::graphics::composer3::Color color) = 0;
[[clang::warn_unused_result]] virtual hal::Error setCompositionType(
aidl::android::hardware::graphics::composer3::Composition type) = 0;
[[clang::warn_unused_result]] virtual hal::Error setDataspace(hal::Dataspace dataspace) = 0;
@@ -305,6 +309,8 @@
// AIDL HAL
[[clang::warn_unused_result]] virtual hal::Error setWhitePointNits(float whitePointNits) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setBlockingRegion(
+ const android::Region& region) = 0;
};
namespace impl {
@@ -328,7 +334,7 @@
hal::Error setSurfaceDamage(const android::Region& damage) override;
hal::Error setBlendMode(hal::BlendMode mode) override;
- hal::Error setColor(hal::Color color) override;
+ hal::Error setColor(aidl::android::hardware::graphics::composer3::Color color) override;
hal::Error setCompositionType(
aidl::android::hardware::graphics::composer3::Composition type) override;
hal::Error setDataspace(hal::Dataspace dataspace) override;
@@ -351,6 +357,7 @@
// AIDL HAL
hal::Error setWhitePointNits(float whitePointNits) override;
+ hal::Error setBlockingRegion(const android::Region& region) override;
private:
// These are references to data owned by HWC2::Device, which will outlive
@@ -366,6 +373,7 @@
// multiple times.
android::Region mVisibleRegion = android::Region::INVALID_REGION;
android::Region mDamageRegion = android::Region::INVALID_REGION;
+ android::Region mBlockingRegion = android::Region::INVALID_REGION;
hal::Dataspace mDataSpace = hal::Dataspace::UNKNOWN;
android::HdrMetadata mHdrMetadata;
android::mat4 mColorMatrix;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 546e677..057db46 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -782,12 +782,13 @@
return NO_ERROR;
}
-std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
- float brightness) {
+std::future<status_t> HWComposer::setDisplayBrightness(
+ PhysicalDisplayId displayId, float brightness,
+ const Hwc2::Composer::DisplayBrightnessOptions& options) {
RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
auto& display = mDisplayData[displayId].hwcDisplay;
- return ftl::chain(display->setDisplayBrightness(brightness))
+ return ftl::chain(display->setDisplayBrightness(brightness, options))
.then([displayId](hal::Error error) -> status_t {
if (error == hal::Error::UNSUPPORTED) {
RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 69adfcd..4fae06d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -192,7 +192,9 @@
DisplayedFrameStats* outStats) = 0;
// Sets the brightness of a display.
- virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
+ virtual std::future<status_t> setDisplayBrightness(
+ PhysicalDisplayId, float brightness,
+ const Hwc2::Composer::DisplayBrightnessOptions&) = 0;
// Events handling ---------------------------------------------------------
@@ -340,7 +342,9 @@
uint64_t maxFrames) override;
status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) override;
- std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
+ std::future<status_t> setDisplayBrightness(
+ PhysicalDisplayId, float brightness,
+ const Hwc2::Composer::DisplayBrightnessOptions&) override;
// Events handling ---------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/Hal.h b/services/surfaceflinger/DisplayHardware/Hal.h
index ee06e03..40c9761 100644
--- a/services/surfaceflinger/DisplayHardware/Hal.h
+++ b/services/surfaceflinger/DisplayHardware/Hal.h
@@ -51,7 +51,6 @@
using Attribute = IComposerClient::Attribute;
using BlendMode = IComposerClient::BlendMode;
-using Color = IComposerClient::Color;
using Connection = IComposerCallback::Connection;
using ContentType = IComposerClient::ContentType;
using Capability = IComposer::Capability;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 7946002..0ab1cfb 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -161,6 +161,7 @@
case OptionalFeature::RefreshRateSwitching:
return mClient_2_4 != nullptr;
case OptionalFeature::ExpectedPresentTime:
+ case OptionalFeature::DisplayBrightnessCommand:
return false;
}
}
@@ -625,11 +626,29 @@
return Error::NONE;
}
-Error HidlComposer::setLayerColor(Display display, Layer layer,
- const IComposerClient::Color& color) {
+static IComposerClient::Color to_hidl_type(
+ aidl::android::hardware::graphics::composer3::Color color) {
+ const auto floatColorToUint8Clamped = [](float val) -> uint8_t {
+ const auto intVal = static_cast<uint64_t>(std::round(255.0f * val));
+ const auto minVal = static_cast<uint64_t>(0);
+ const auto maxVal = static_cast<uint64_t>(255);
+ return std::clamp(intVal, minVal, maxVal);
+ };
+
+ return IComposerClient::Color{
+ floatColorToUint8Clamped(color.r),
+ floatColorToUint8Clamped(color.g),
+ floatColorToUint8Clamped(color.b),
+ floatColorToUint8Clamped(color.a),
+ };
+}
+
+Error HidlComposer::setLayerColor(
+ Display display, Layer layer,
+ const aidl::android::hardware::graphics::composer3::Color& color) {
mWriter.selectDisplay(display);
mWriter.selectLayer(layer);
- mWriter.setLayerColor(color);
+ mWriter.setLayerColor(to_hidl_type(color));
return Error::NONE;
}
@@ -1013,7 +1032,8 @@
return Error::NONE;
}
-Error HidlComposer::setDisplayBrightness(Display display, float brightness) {
+Error HidlComposer::setDisplayBrightness(Display display, float brightness,
+ const DisplayBrightnessOptions&) {
if (!mClient_2_3) {
return Error::UNSUPPORTED;
}
@@ -1208,6 +1228,11 @@
return Error::NONE;
}
+Error HidlComposer::setLayerBlockingRegion(Display, Layer,
+ const std::vector<IComposerClient::Rect>&) {
+ return Error::NONE;
+}
+
CommandReader::~CommandReader() {
resetData();
}
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 3b62fe0..8282d8a 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -248,7 +248,8 @@
Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& damage) override;
Error setLayerBlendMode(Display display, Layer layer, IComposerClient::BlendMode mode) override;
- Error setLayerColor(Display display, Layer layer, const IComposerClient::Color& color) override;
+ Error setLayerColor(Display display, Layer layer,
+ const aidl::android::hardware::graphics::composer3::Color& color) override;
Error setLayerCompositionType(
Display display, Layer layer,
aidl::android::hardware::graphics::composer3::Composition type) override;
@@ -289,7 +290,8 @@
Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override;
- Error setDisplayBrightness(Display display, float brightness) override;
+ Error setDisplayBrightness(Display display, float brightness,
+ const DisplayBrightnessOptions& options) override;
// Composer HAL 2.4
Error getDisplayCapabilities(
@@ -316,7 +318,11 @@
Error getClientTargetProperty(Display display,
IComposerClient::ClientTargetProperty* outClientTargetProperty,
float* outWhitePointNits) override;
+
+ // AIDL Composer HAL
Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
+ Error setLayerBlockingRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& blocking) override;
private:
class CommandWriter : public CommandWriterBase {
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 930ddea..6f02843 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -295,10 +295,6 @@
}
mSupportsPowerHint = checkPowerHintSessionSupported();
-
- if (mSupportsPowerHint) {
- mPowerHintQueue.reserve(kMaxQueueSize);
- }
}
~AidlPowerHalWrapper() override {
@@ -423,8 +419,9 @@
}
bool shouldReportActualDurationsNow() {
- // report if we have never reported before or have exceeded the max queue size
- if (!mLastActualDurationSent.has_value() || mPowerHintQueue.size() >= kMaxQueueSize) {
+ // report if we have never reported before or are approaching a stale session
+ if (!mLastActualDurationSent.has_value() ||
+ (systemTime() - mLastActualReportTimestamp) > kStaleTimeout.count()) {
return true;
}
@@ -477,6 +474,7 @@
// are outlined in shouldReportActualDurationsNow()
if (shouldReportActualDurationsNow()) {
ALOGV("Sending hint update batch");
+ mLastActualReportTimestamp = systemTime();
auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
if (!ret.isOk()) {
ALOGW("Failed to report actual work durations with error: %s",
@@ -506,27 +504,30 @@
// Queue of actual durations saved to report
std::vector<WorkDuration> mPowerHintQueue;
// The latest un-normalized values we have received for target and actual
- int64_t mTargetDuration = kDefaultTarget;
+ int64_t mTargetDuration = kDefaultTarget.count();
std::optional<int64_t> mActualDuration;
// The list of thread ids, stored so we can restart the session from this class if needed
std::vector<int32_t> mPowerHintThreadIds;
bool mSupportsPowerHint;
// Keep track of the last messages sent for rate limiter change detection
std::optional<int64_t> mLastActualDurationSent;
- int64_t mLastTargetDurationSent = kDefaultTarget;
+ // timestamp of the last report we sent, used to avoid stale sessions
+ int64_t mLastActualReportTimestamp = 0;
+ int64_t mLastTargetDurationSent = kDefaultTarget.count();
// Whether to normalize all the actual values as error terms relative to a constant target
// This saves a binder call by not setting the target, and should not affect the pid values
static const bool sNormalizeTarget;
// Whether we should emit ATRACE_INT data for hint sessions
static const bool sTraceHintSessionData;
- // Max number of messages allowed in mPowerHintQueue before reporting is forced
- static constexpr int32_t kMaxQueueSize = 15;
// Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
static constexpr double kAllowedActualDeviationPercent = 0.1;
// Max percent the target duration can vary without causing a report (eg: 0.05 = 5%)
static constexpr double kAllowedTargetDeviationPercent = 0.05;
// Target used for init and normalization, the actual value does not really matter
- static constexpr int64_t kDefaultTarget = 50000000;
+ static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
+ // amount of time after the last message was sent before the session goes stale
+ // actually 100ms but we use 80 here to ideally avoid going stale
+ static constexpr const std::chrono::nanoseconds kStaleTimeout = 80ms;
};
const bool AidlPowerHalWrapper::sTraceHintSessionData =
diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp
index 22c3a70..68f9321 100644
--- a/services/surfaceflinger/Scheduler/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/Timer.cpp
@@ -51,13 +51,25 @@
}
void Timer::reset() {
- cleanup();
- mTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
- mEpollFd = epoll_create1(EPOLL_CLOEXEC);
- if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
- ALOGE("could not create TimerDispatch mPipes");
- return;
- };
+ std::function<void()> cb;
+ {
+ std::lock_guard lock(mMutex);
+ if (mExpectingCallback && mCallback) {
+ cb = mCallback;
+ }
+
+ cleanup();
+ mTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+ mEpollFd = epoll_create1(EPOLL_CLOEXEC);
+ if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
+ ALOGE("could not create TimerDispatch mPipes");
+ }
+ }
+ if (cb) {
+ setDebugState(DebugState::InCallback);
+ cb();
+ setDebugState(DebugState::Running);
+ }
setDebugState(DebugState::Reset);
}
@@ -81,6 +93,8 @@
close(mPipes[kWritePipe]);
mPipes[kWritePipe] = -1;
}
+ mExpectingCallback = false;
+ mCallback = {};
}
void Timer::endDispatch() {
@@ -99,6 +113,7 @@
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
mCallback = cb;
+ mExpectingCallback = true;
struct itimerspec old_timer;
struct itimerspec new_timer {
@@ -198,6 +213,7 @@
{
std::lock_guard lock(mMutex);
cb = mCallback;
+ mExpectingCallback = false;
}
if (cb) {
setDebugState(DebugState::InCallback);
diff --git a/services/surfaceflinger/Scheduler/Timer.h b/services/surfaceflinger/Scheduler/Timer.h
index 628d800..eb65954 100644
--- a/services/surfaceflinger/Scheduler/Timer.h
+++ b/services/surfaceflinger/Scheduler/Timer.h
@@ -36,6 +36,10 @@
void alarmCancel() final;
void dump(std::string& result) const final;
+protected:
+ // For unit testing
+ int mEpollFd = -1;
+
private:
enum class DebugState {
Reset,
@@ -48,12 +52,12 @@
ftl_last = Terminated
};
- void reset();
- void cleanup();
+ void reset() EXCLUDES(mMutex);
+ void cleanup() REQUIRES(mMutex);
void setDebugState(DebugState state) EXCLUDES(mMutex);
int mTimerFd = -1;
- int mEpollFd = -1;
+
std::array<int, 2> mPipes = {-1, -1};
std::thread mDispatchThread;
@@ -63,6 +67,7 @@
mutable std::mutex mMutex;
std::function<void()> mCallback GUARDED_BY(mMutex);
+ bool mExpectingCallback GUARDED_BY(mMutex) = false;
DebugState mDebugState GUARDED_BY(mMutex);
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bd13c41..3d6bcb7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -339,7 +339,6 @@
ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
-bool SurfaceFlinger::enableSdrDimming;
LatchUnsignaledConfig SurfaceFlinger::enableLatchUnsignaledConfig;
std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
@@ -503,9 +502,6 @@
mRefreshRateOverlaySpinner = property_get_bool("sf.debug.show_refresh_rate_overlay_spinner", 0);
- // Debug property overrides ro. property
- enableSdrDimming = property_get_bool("debug.sf.enable_sdr_dimming", enable_sdr_dimming(false));
-
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
mTransactionTracingEnabled =
@@ -1679,6 +1675,17 @@
return NO_ERROR;
}
+bool SurfaceFlinger::hasVisibleHdrLayer(const sp<DisplayDevice>& display) {
+ bool hasHdrLayers = false;
+ mDrawingState.traverse([&,
+ compositionDisplay = display->getCompositionDisplay()](Layer* layer) {
+ hasHdrLayers |= (layer->isVisible() &&
+ compositionDisplay->includesLayer(layer->getCompositionEngineLayerFE()) &&
+ isHdrDataspace(layer->getDataSpace()));
+ });
+ return hasHdrLayers;
+}
+
status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
const gui::DisplayBrightness& brightness) {
if (!displayToken) {
@@ -1688,13 +1695,30 @@
const char* const whence = __func__;
return ftl::chain(mScheduler->schedule([=]() MAIN_THREAD {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
- if (enableSdrDimming) {
+ const bool supportsDisplayBrightnessCommand =
+ getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
+ // If we support applying display brightness as a command, then we also support
+ // dimming SDR layers.
+ if (supportsDisplayBrightnessCommand) {
display->getCompositionDisplay()
->setDisplayBrightness(brightness.sdrWhitePointNits,
brightness.displayBrightnessNits);
+ MAIN_THREAD_GUARD(display->stageBrightness(brightness.displayBrightness));
+ if (hasVisibleHdrLayer(display)) {
+ scheduleComposite(FrameHint::kNone);
+ } else {
+ scheduleCommit(FrameHint::kNone);
+ }
+ return ftl::yield<status_t>(OK);
+ } else {
+ return getHwComposer()
+ .setDisplayBrightness(display->getPhysicalId(),
+ brightness.displayBrightness,
+ Hwc2::Composer::DisplayBrightnessOptions{
+ .applyImmediately = true});
}
- return getHwComposer().setDisplayBrightness(display->getPhysicalId(),
- brightness.displayBrightness);
+
} else {
ALOGE("%s: Invalid display token %p", whence, displayToken.get());
return ftl::yield<status_t>(NAME_NOT_FOUND);
@@ -2035,7 +2059,10 @@
// We received the present fence from the HWC, so we assume it successfully updated
// the mode, hence we update SF.
mSetActiveModePending = false;
- ON_MAIN_THREAD(updateInternalStateWithChangedMode());
+ {
+ Mutex::Autolock lock(mStateLock);
+ updateInternalStateWithChangedMode();
+ }
}
if (framePending) {
@@ -2100,13 +2127,14 @@
{
Mutex::Autolock _l(mStateLock);
mScheduler->chooseRefreshRateForContent();
+ setActiveModeInHwcIfNeeded();
}
- ON_MAIN_THREAD(setActiveModeInHwcIfNeeded());
-
updateCursorAsync();
updateInputFlinger();
+ MAIN_THREAD_GUARD(persistDisplayBrightness(mustComposite));
+
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}
@@ -3155,6 +3183,34 @@
mInputWindowCommands.clear();
}
+void SurfaceFlinger::persistDisplayBrightness(bool needsComposite) {
+ const bool supportsDisplayBrightnessCommand = getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
+ if (!supportsDisplayBrightnessCommand) {
+ return;
+ }
+
+ const auto& displays = ON_MAIN_THREAD(mDisplays);
+
+ for (const auto& [_, display] : displays) {
+ if (const auto brightness = display->getStagedBrightness(); brightness) {
+ if (!needsComposite) {
+ const status_t error =
+ getHwComposer()
+ .setDisplayBrightness(display->getPhysicalId(), *brightness,
+ Hwc2::Composer::DisplayBrightnessOptions{
+ .applyImmediately = true})
+ .get();
+
+ ALOGE_IF(error != NO_ERROR,
+ "Error setting display brightness for display %s: %d (%s)",
+ display->getDebugName().c_str(), error, strerror(error));
+ }
+ display->persistBrightness(needsComposite);
+ }
+ }
+}
+
void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
std::vector<DisplayInfo>& outDisplayInfos) {
struct Details {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0c4236f..61cfb4e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -252,10 +252,6 @@
static constexpr SkipInitializationTag SkipInitialization;
- // Whether or not SDR layers should be dimmed to the desired SDR white point instead of
- // being treated as native display brightness
- static bool enableSdrDimming;
-
static LatchUnsignaledConfig enableLatchUnsignaledConfig;
// must be called before clients can connect
@@ -676,6 +672,9 @@
void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode)
REQUIRES(mStateLock);
+ // Returns true if the display has a visible HDR layer in its layer stack.
+ bool hasVisibleHdrLayer(const sp<DisplayDevice>& display) REQUIRES(mStateLock);
+
// Sets the desired display mode specs.
status_t setDesiredDisplayModeSpecsInternal(
const sp<DisplayDevice>& display,
@@ -692,6 +691,7 @@
void updateLayerGeometry();
void updateInputFlinger();
+ void persistDisplayBrightness(bool needsComposite) REQUIRES(SF_MAIN_THREAD);
void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos,
std::vector<gui::DisplayInfo>& outDisplayInfos);
void commitInputWindowCommands() REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 5568418..bba880e 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -55,6 +55,7 @@
"DisplayTransactionTest.cpp",
"DisplayDevice_GetBestColorModeTest.cpp",
"DisplayDevice_InitiateModeChange.cpp",
+ "DisplayDevice_SetDisplayBrightnessTest.cpp",
"DisplayDevice_SetProjectionTest.cpp",
"EventThreadTest.cpp",
"FlagManagerTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index f1e9b31..6c96d5f 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -621,7 +621,8 @@
// TODO: use COLOR
EXPECT_CALL(*test->mComposer,
setLayerColor(HWC_DISPLAY, HWC_LAYER,
- IComposerClient::Color({0xff, 0xff, 0xff, 0xff})))
+ aidl::android::hardware::graphics::composer3::Color(
+ {1.0f, 1.0f, 1.0f, 1.0f})))
.Times(1);
}
}
diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp
new file mode 100644
index 0000000..73c60e1
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2021 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 "LibSurfaceFlingerUnittests"
+
+#include "DisplayTransactionTestHelpers.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace {
+
+using hal::RenderIntent;
+
+using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
+
+class SetDisplayBrightnessTest : public DisplayTransactionTest {
+public:
+ sp<DisplayDevice> getDisplayDevice() { return injectDefaultInternalDisplay({}); }
+};
+
+TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessNoComposite) {
+ MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ sp<DisplayDevice> displayDevice = getDisplayDevice();
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+
+ constexpr float kDisplayBrightness = 0.5f;
+ displayDevice->stageBrightness(kDisplayBrightness);
+
+ EXPECT_EQ(0.5f, displayDevice->getStagedBrightness());
+
+ displayDevice->persistBrightness(false);
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+ EXPECT_EQ(std::nullopt, displayDevice->getCompositionDisplay()->getState().displayBrightness);
+}
+
+TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessWithComposite) {
+ MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ sp<DisplayDevice> displayDevice = getDisplayDevice();
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+
+ constexpr float kDisplayBrightness = 0.5f;
+ displayDevice->stageBrightness(kDisplayBrightness);
+
+ EXPECT_EQ(0.5f, displayDevice->getStagedBrightness());
+
+ displayDevice->persistBrightness(true);
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+ EXPECT_EQ(kDisplayBrightness,
+ displayDevice->getCompositionDisplay()->getState().displayBrightness);
+}
+
+TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessWithCompositeShortCircuitsOnNoOp) {
+ MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ sp<DisplayDevice> displayDevice = getDisplayDevice();
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+
+ constexpr float kDisplayBrightness = 0.5f;
+ displayDevice->stageBrightness(kDisplayBrightness);
+
+ EXPECT_EQ(0.5f, displayDevice->getStagedBrightness());
+
+ displayDevice->persistBrightness(true);
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+ EXPECT_EQ(kDisplayBrightness,
+ displayDevice->getCompositionDisplay()->getState().displayBrightness);
+ displayDevice->getCompositionDisplay()->editState().displayBrightness = std::nullopt;
+
+ displayDevice->stageBrightness(kDisplayBrightness);
+ EXPECT_EQ(0.5f, displayDevice->getStagedBrightness());
+ displayDevice->persistBrightness(true);
+
+ EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
+ EXPECT_EQ(std::nullopt, displayDevice->getCompositionDisplay()->getState().displayBrightness);
+}
+
+} // namespace
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index b1f704a..c318e28 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -60,6 +60,7 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
+ mFlinger.resetScheduler(nullptr);
}
void DisplayTransactionTest::injectMockScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 0067997..361d629 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -347,6 +347,11 @@
auto notifyPowerBoost(int32_t boostId) { return mFlinger->notifyPowerBoost(boostId); }
+ auto setDisplayBrightness(const sp<IBinder>& display,
+ const gui::DisplayBrightness& brightness) {
+ return mFlinger->setDisplayBrightness(display, brightness);
+ }
+
// Allow reading display state without locking, as if called on the SF main thread.
auto setPowerModeInternal(const sp<DisplayDevice>& display,
hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS {
diff --git a/services/surfaceflinger/tests/unittests/TimerTest.cpp b/services/surfaceflinger/tests/unittests/TimerTest.cpp
index cda6bbf..0a3639d 100644
--- a/services/surfaceflinger/tests/unittests/TimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TimerTest.cpp
@@ -26,11 +26,19 @@
namespace android::scheduler {
+struct TestableTimer : public Timer {
+public:
+ void makeEpollError() {
+ // close the epoll file descriptor to cause an epoll error
+ close(mEpollFd);
+ }
+};
+
struct TimerTest : testing::Test {
static constexpr int mIterations = 20;
AsyncCallRecorder<void (*)()> mCallbackRecorder;
- Timer mTimer;
+ TestableTimer mTimer;
void timerCallback() { mCallbackRecorder.recordCall(); }
};
@@ -42,4 +50,14 @@
EXPECT_FALSE(mCallbackRecorder.waitForUnexpectedCall().has_value());
}
}
+
+TEST_F(TimerTest, recoversAfterEpollError) {
+ for (int i = 0; i < mIterations; i++) {
+ mTimer.makeEpollError();
+ mTimer.alarmAt(std::bind(&TimerTest::timerCallback, this), systemTime() - 10'000'00);
+ EXPECT_TRUE(mCallbackRecorder.waitForCall().has_value());
+ EXPECT_FALSE(mCallbackRecorder.waitForUnexpectedCall().has_value());
+ }
+}
+
} // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 8c51313..ecdadf7 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -97,7 +97,8 @@
MOCK_METHOD3(setLayerSurfaceDamage,
Error(Display, Layer, const std::vector<IComposerClient::Rect>&));
MOCK_METHOD3(setLayerBlendMode, Error(Display, Layer, IComposerClient::BlendMode));
- MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&));
+ MOCK_METHOD3(setLayerColor,
+ Error(Display, Layer, const aidl::android::hardware::graphics::composer3::Color&));
MOCK_METHOD3(setLayerCompositionType,
Error(Display, Layer, aidl::android::hardware::graphics::composer3::Composition));
MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace));
@@ -120,7 +121,7 @@
Error(Display, uint64_t, uint64_t, DisplayedFrameStats*));
MOCK_METHOD3(setLayerPerFrameMetadataBlobs,
Error(Display, Layer, const std::vector<IComposerClient::PerFrameMetadataBlob>&));
- MOCK_METHOD2(setDisplayBrightness, Error(Display, float));
+ MOCK_METHOD3(setDisplayBrightness, Error(Display, float, const DisplayBrightnessOptions&));
MOCK_METHOD2(
getDisplayCapabilities,
Error(Display,
@@ -145,6 +146,8 @@
MOCK_METHOD3(getClientTargetProperty,
Error(Display, IComposerClient::ClientTargetProperty*, float*));
MOCK_METHOD3(setLayerWhitePointNits, Error(Display, Layer, float));
+ MOCK_METHOD3(setLayerBlockingRegion,
+ Error(Display, Layer, const std::vector<IComposerClient::Rect>&));
};
} // namespace Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index 821fc8f..7ac0c78 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -80,7 +80,8 @@
MOCK_METHOD(hal::Error, presentOrValidate,
(nsecs_t, uint32_t *, uint32_t *, android::sp<android::Fence> *, uint32_t *),
(override));
- MOCK_METHOD(std::future<hal::Error>, setDisplayBrightness, (float), (override));
+ MOCK_METHOD(std::future<hal::Error>, setDisplayBrightness,
+ (float, const Hwc2::Composer::DisplayBrightnessOptions &), (override));
MOCK_METHOD(hal::Error, setActiveConfigWithConstraints,
(hal::HWConfigId, const hal::VsyncPeriodChangeConstraints &,
hal::VsyncPeriodChangeTimeline *),
@@ -106,7 +107,8 @@
(override));
MOCK_METHOD(hal::Error, setSurfaceDamage, (const android::Region &), (override));
MOCK_METHOD(hal::Error, setBlendMode, (hal::BlendMode), (override));
- MOCK_METHOD(hal::Error, setColor, (hal::Color), (override));
+ MOCK_METHOD(hal::Error, setColor, (aidl::android::hardware::graphics::composer3::Color),
+ (override));
MOCK_METHOD(hal::Error, setCompositionType,
(aidl::android::hardware::graphics::composer3::Composition), (override));
MOCK_METHOD(hal::Error, setDataspace, (android::ui::Dataspace), (override));
@@ -123,6 +125,7 @@
MOCK_METHOD(hal::Error, setLayerGenericMetadata,
(const std::string &, bool, const std::vector<uint8_t> &), (override));
MOCK_METHOD(hal::Error, setWhitePointNits, (float whitePointNits), (override));
+ MOCK_METHOD(hal::Error, setBlockingRegion, (const android::Region &), (override));
};
} // namespace android::HWC2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockLayer.h b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
index 8b48e1c..0840a2f 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockLayer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
@@ -34,6 +34,7 @@
MOCK_METHOD0(createClone, sp<Layer>());
MOCK_CONST_METHOD0(getFrameRateForLayerTree, FrameRate());
MOCK_CONST_METHOD0(getOwnerUid, uid_t());
+ MOCK_CONST_METHOD0(getDataSpace, ui::Dataspace());
};
} // namespace android::mock