diff options
45 files changed, 623 insertions, 190 deletions
diff --git a/cmds/atrace/atrace_userdebug.rc b/cmds/atrace/atrace_userdebug.rc index 5c28c9df81..6c86c21387 100644 --- a/cmds/atrace/atrace_userdebug.rc +++ b/cmds/atrace/atrace_userdebug.rc @@ -5,6 +5,12 @@ # Access control to these files is now entirely in selinux policy. on post-fs + # On userdebug allow to enable any event via the generic + # set_event interface: + # echo sched/foo > set_event == echo 1 > events/sched/foo/enable. + chmod 0666 /sys/kernel/tracing/set_event + chmod 0666 /sys/kernel/debug/tracing/set_event + chmod 0666 /sys/kernel/tracing/events/workqueue/enable chmod 0666 /sys/kernel/debug/tracing/events/workqueue/enable chmod 0666 /sys/kernel/tracing/events/regulator/enable diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp index 909bdd7134..6596fa246c 100644 --- a/cmds/dumpstate/DumpstateService.cpp +++ b/cmds/dumpstate/DumpstateService.cpp @@ -98,11 +98,10 @@ binder::Status DumpstateService::setListener(const std::string& name, return binder::Status::ok(); } -binder::Status DumpstateService::startBugreport(const android::base::unique_fd& /* bugreportFd */, - const android::base::unique_fd& /* screenshotFd */, +binder::Status DumpstateService::startBugreport(const android::base::unique_fd& bugreport_fd, + const android::base::unique_fd& screenshot_fd, int bugreport_mode, - const sp<IDumpstateListener>& /* listener */) { - // TODO(b/111441001): Pass in fds & other arguments to DumpOptions. + const sp<IDumpstateListener>& listener) { MYLOGI("startBugreport() with mode: %d\n", bugreport_mode); if (bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_FULL && @@ -116,9 +115,20 @@ binder::Status DumpstateService::startBugreport(const android::base::unique_fd& StringPrintf("Invalid bugreport mode: %d", bugreport_mode)); } + if (bugreport_fd.get() == -1 || screenshot_fd.get() == -1) { + return exception(binder::Status::EX_ILLEGAL_ARGUMENT, "Invalid file descriptor"); + } + std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>(); - options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode)); + options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode), bugreport_fd, + screenshot_fd); + + std::lock_guard<std::mutex> lock(lock_); + // TODO(b/111441001): Disallow multiple simultaneous bugreports. ds_.SetOptions(std::move(options)); + if (listener != nullptr) { + ds_.listener_ = listener; + } pthread_t thread; status_t err = pthread_create(&thread, nullptr, callAndNotify, &ds_); diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h index 1736ae8066..1705317bdb 100644 --- a/cmds/dumpstate/DumpstateService.h +++ b/cmds/dumpstate/DumpstateService.h @@ -42,8 +42,8 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst bool getSectionDetails, sp<IDumpstateToken>* returned_token) override; - binder::Status startBugreport(const android::base::unique_fd& bugreportFd, - const android::base::unique_fd& screenshotFd, int bugreport_mode, + binder::Status startBugreport(const android::base::unique_fd& bugreport_fd, + const android::base::unique_fd& screenshot_fd, int bugreport_mode, const sp<IDumpstateListener>& listener) override; private: diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl index ba3e290fd9..d24c953fa2 100644 --- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl +++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl @@ -25,8 +25,6 @@ import android.os.DumpstateOptions; * {@hide} */ interface IDumpstate { - - // TODO: remove method once startBugReport is used by Shell. /* * Sets the listener for this dumpstate progress. @@ -69,6 +67,6 @@ interface IDumpstate { * @param bugreportMode the mode that specifies other run time options; must be one of above * @param listener callback for updates; optional */ - void startBugreport(FileDescriptor bugreportFd, FileDescriptor screenshotFd, int bugreportMode, - IDumpstateListener listener); + void startBugreport(FileDescriptor bugreportFd, FileDescriptor screenshotFd, int bugreportMode, + IDumpstateListener listener); } diff --git a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl index 030d69d16e..2966c86ee9 100644 --- a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl +++ b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl @@ -22,18 +22,48 @@ package android.os; * {@hide} */ interface IDumpstateListener { + /** + * Called when there is a progress update. + * + * @param progress the progress in [0, 100] + */ + oneway void onProgress(int progress); + + /* Options specified are invalid or incompatible */ + const int BUGREPORT_ERROR_INVALID_INPUT = 1; + + /* Bugreport encountered a runtime error */ + const int BUGREPORT_ERROR_RUNTIME_ERROR = 2; + + /** + * Called on an error condition with one of the error codes listed above. + */ + oneway void onError(int errorCode); + + /** + * Called when taking bugreport finishes successfully + * + * @param durationMs time capturing bugreport took in milliseconds + * @param title title for the bugreport; helpful in reminding the user why they took it + * @param description detailed description for the bugreport + */ + oneway void onFinished(long durationMs, @utf8InCpp String title, + @utf8InCpp String description); + + // TODO(b/111441001): Remove old methods when not used anymore. void onProgressUpdated(int progress); void onMaxProgressUpdated(int maxProgress); /** - * Called after every section is complete. - * @param name section name - * @param status values from status_t - * {@code OK} section completed successfully - * {@code TIMEOUT} dump timed out - * {@code != OK} error - * @param size size in bytes, may be invalid if status != OK - * @param durationMs duration in ms - */ + * Called after every section is complete. + * + * @param name section name + * @param status values from status_t + * {@code OK} section completed successfully + * {@code TIMEOUT} dump timed out + * {@code != OK} error + * @param size size in bytes, may be invalid if status != OK + * @param durationMs duration in ms + */ void onSectionComplete(@utf8InCpp String name, int status, int size, int durationMs); } diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 47c4f62d11..4e5d68dc5c 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -1881,8 +1881,9 @@ static void PrepareToWriteToFile() { ds.tmp_path_ = ds.GetPath(".tmp"); ds.log_path_ = ds.GetPath("-dumpstate_log-" + std::to_string(ds.pid_) + ".txt"); - std::string destination = ds.options_->fd != -1 ? StringPrintf("[fd:%d]", ds.options_->fd) - : ds.bugreport_dir_.c_str(); + std::string destination = ds.options_->bugreport_fd.get() != -1 + ? StringPrintf("[fd:%d]", ds.options_->bugreport_fd.get()) + : ds.bugreport_dir_.c_str(); MYLOGD( "Bugreport dir: %s\n" "Internal Bugreport dir: %s\n" @@ -1960,8 +1961,8 @@ static void FinalizeFile() { } // The zip file lives in an internal directory. Copy it over to output. bool copy_succeeded = false; - if (ds.options_->fd != -1) { - copy_succeeded = android::os::CopyFileToFd(ds.path_, ds.options_->fd); + if (ds.options_->bugreport_fd.get() != -1) { + copy_succeeded = android::os::CopyFileToFd(ds.path_, ds.options_->bugreport_fd.get()); } else { ds.final_path_ = ds.GetPath(ds.bugreport_dir_, ".zip"); copy_succeeded = android::os::CopyFileToFile(ds.path_, ds.final_path_); @@ -2164,7 +2165,7 @@ static void LogDumpOptions(const Dumpstate::DumpOptions& options) { MYLOGI("telephony_only: %d\n", options.telephony_only); MYLOGI("wifi_only: %d\n", options.wifi_only); MYLOGI("do_progress_updates: %d\n", options.do_progress_updates); - MYLOGI("fd: %d\n", options.fd); + MYLOGI("fd: %d\n", options.bugreport_fd.get()); MYLOGI("use_outfile: %s\n", options.use_outfile.c_str()); MYLOGI("extra_options: %s\n", options.extra_options.c_str()); MYLOGI("args: %s\n", options.args.c_str()); @@ -2172,14 +2173,17 @@ static void LogDumpOptions(const Dumpstate::DumpOptions& options) { MYLOGI("notification_description: %s\n", options.notification_description.c_str()); } -void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode) { +void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode, + const android::base::unique_fd& bugreport_fd_in, + const android::base::unique_fd& screenshot_fd_in) { // In the new API world, date is always added; output is always a zip file. // TODO(111441001): remove these options once they are obsolete. do_add_date = true; do_zip_file = true; - // STOPSHIP b/111441001: Remove hardcoded output file path; accept fd. - use_outfile = "/data/user_de/0/com.android.shell/files/bugreports/bugreport"; + // Duplicate the fds because the passed in fds don't outlive the binder transaction. + bugreport_fd.reset(dup(bugreport_fd_in.get())); + screenshot_fd.reset(dup(screenshot_fd_in.get())); extra_options = ModeToString(bugreport_mode); SetOptionsFromMode(bugreport_mode, this); @@ -2230,11 +2234,11 @@ Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) } bool Dumpstate::DumpOptions::ValidateOptions() const { - if (fd != -1 && !do_zip_file) { + if (bugreport_fd.get() != -1 && !do_zip_file) { return false; } - bool has_out_file_options = !use_outfile.empty() || fd != -1; + bool has_out_file_options = !use_outfile.empty() || bugreport_fd.get() != -1; if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast) && !has_out_file_options) { return false; diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h index 7ac25e42f0..529111e882 100644 --- a/cmds/dumpstate/dumpstate.h +++ b/cmds/dumpstate/dumpstate.h @@ -342,9 +342,11 @@ class Dumpstate { bool wifi_only = false; // Whether progress updates should be published. bool do_progress_updates = false; - // File descriptor to output zip file. -1 indicates not set. Takes precedence over - // use_outfile. - int fd = -1; + // File descriptor to output zip file. Takes precedence over use_outfile. + android::base::unique_fd bugreport_fd; + // File descriptor to screenshot file. + // TODO(b/111441001): Use this fd. + android::base::unique_fd screenshot_fd; // Partial path to output file. std::string use_outfile; // TODO: rename to MODE. @@ -360,7 +362,8 @@ class Dumpstate { RunStatus Initialize(int argc, char* argv[]); /* Initializes options from the requested mode. */ - void Initialize(BugreportMode bugreport_mode); + void Initialize(BugreportMode bugreport_mode, const android::base::unique_fd& bugreport_fd, + const android::base::unique_fd& screenshot_fd); /* Returns true if the options set so far are consistent. */ bool ValidateOptions() const; diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp index 61a5ef5b7d..c57775fac8 100644 --- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp +++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp @@ -53,6 +53,19 @@ class DumpstateListener : public IDumpstateListener { DumpstateListener(int fd, std::shared_ptr<std::vector<SectionInfo>> sections) : outFd_(fd), max_progress_(5000), sections_(sections) { } + binder::Status onProgress(int32_t progress) override { + dprintf(outFd_, "\rIn progress %d", progress); + return binder::Status::ok(); + } + binder::Status onError(int32_t error_code) override { + dprintf(outFd_, "\rError %d", error_code); + return binder::Status::ok(); + } + binder::Status onFinished(int64_t duration_ms, const ::std::string&, + const ::std::string&) override { + dprintf(outFd_, "\rFinished in %lld", (long long) duration_ms); + return binder::Status::ok(); + } binder::Status onProgressUpdated(int32_t progress) override { dprintf(outFd_, "\rIn progress %d/%d", progress, max_progress_); return binder::Status::ok(); diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp index fcf9371a4f..98ee1b0e01 100644 --- a/cmds/dumpstate/tests/dumpstate_test.cpp +++ b/cmds/dumpstate/tests/dumpstate_test.cpp @@ -59,6 +59,10 @@ using ::testing::internal::GetCapturedStdout; class DumpstateListenerMock : public IDumpstateListener { public: + MOCK_METHOD1(onProgress, binder::Status(int32_t progress)); + MOCK_METHOD1(onError, binder::Status(int32_t error_code)); + MOCK_METHOD3(onFinished, binder::Status(int64_t duration_ms, const ::std::string& title, + const ::std::string& description)); MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress)); MOCK_METHOD1(onMaxProgressUpdated, binder::Status(int32_t max_progress)); MOCK_METHOD4(onSectionComplete, binder::Status(const ::std::string& name, int32_t status, diff --git a/cmds/lshal/Command.h b/cmds/lshal/Command.h index 4f128ab56b..e19e3f7fc2 100644 --- a/cmds/lshal/Command.h +++ b/cmds/lshal/Command.h @@ -27,7 +27,7 @@ class Lshal; // Base class for all *Commands class Command { public: - Command(Lshal& lshal) : mLshal(lshal) {} + explicit Command(Lshal& lshal) : mLshal(lshal) {} virtual ~Command() = default; // Expect optind to be set by Lshal::main and points to the next argument // to process. diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h index 6e12008c8e..3c3f56fde5 100644 --- a/cmds/lshal/DebugCommand.h +++ b/cmds/lshal/DebugCommand.h @@ -31,7 +31,7 @@ class Lshal; class DebugCommand : public Command { public: - DebugCommand(Lshal &lshal) : Command(lshal) {} + explicit DebugCommand(Lshal &lshal) : Command(lshal) {} ~DebugCommand() = default; Status main(const Arg &arg) override; void usage() const override; diff --git a/cmds/lshal/HelpCommand.h b/cmds/lshal/HelpCommand.h index cc709f8ee4..da0cba6f42 100644 --- a/cmds/lshal/HelpCommand.h +++ b/cmds/lshal/HelpCommand.h @@ -31,7 +31,7 @@ class Lshal; class HelpCommand : public Command { public: - HelpCommand(Lshal &lshal) : Command(lshal) {} + explicit HelpCommand(Lshal &lshal) : Command(lshal) {} ~HelpCommand() = default; Status main(const Arg &arg) override; void usage() const override; diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h index 3f7321d681..85195fcc54 100644 --- a/cmds/lshal/ListCommand.h +++ b/cmds/lshal/ListCommand.h @@ -57,7 +57,7 @@ enum class HalType { class ListCommand : public Command { public: - ListCommand(Lshal &lshal) : Command(lshal) {} + explicit ListCommand(Lshal &lshal) : Command(lshal) {} virtual ~ListCommand() = default; Status main(const Arg &arg) override; void usage() const override; diff --git a/cmds/lshal/NullableOStream.h b/cmds/lshal/NullableOStream.h index ab37a04c56..737d3a2963 100644 --- a/cmds/lshal/NullableOStream.h +++ b/cmds/lshal/NullableOStream.h @@ -25,8 +25,8 @@ namespace lshal { template<typename S> class NullableOStream { public: - NullableOStream(S &os) : mOs(&os) {} - NullableOStream(S *os) : mOs(os) {} + explicit NullableOStream(S &os) : mOs(&os) {} + explicit NullableOStream(S *os) : mOs(os) {} NullableOStream &operator=(S &os) { mOs = &os; return *this; @@ -57,7 +57,7 @@ public: S& buf() const { return *mOs; } - operator bool() const { + operator bool() const { // NOLINT(google-explicit-constructor) return mOs != nullptr; } private: diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h index 7294b0a134..601b7e25f9 100644 --- a/cmds/lshal/TableEntry.h +++ b/cmds/lshal/TableEntry.h @@ -149,7 +149,7 @@ using TableEntryCompare = std::function<bool(const TableEntry &, const TableEntr class MergedTable { public: - MergedTable(std::vector<const Table*>&& tables) : mTables(std::move(tables)) {} + explicit MergedTable(std::vector<const Table*>&& tables) : mTables(std::move(tables)) {} TextTable createTextTable(); private: std::vector<const Table*> mTables; diff --git a/cmds/lshal/TextTable.h b/cmds/lshal/TextTable.h index 91d522aef7..301b4bd969 100644 --- a/cmds/lshal/TextTable.h +++ b/cmds/lshal/TextTable.h @@ -33,11 +33,11 @@ public: TextTableRow() {} // A row of cells. - TextTableRow(std::vector<std::string>&& v) : mFields(std::move(v)) {} + explicit TextTableRow(std::vector<std::string>&& v) : mFields(std::move(v)) {} // A single comment string. - TextTableRow(std::string&& s) : mLine(std::move(s)) {} - TextTableRow(const std::string& s) : mLine(s) {} + explicit TextTableRow(std::string&& s) : mLine(std::move(s)) {} + explicit TextTableRow(const std::string& s) : mLine(s) {} // Whether this row is an actual row of cells. bool isRow() const { return !fields().empty(); } diff --git a/cmds/lshal/Timeout.h b/cmds/lshal/Timeout.h index 58119a6fcf..46d817759d 100644 --- a/cmds/lshal/Timeout.h +++ b/cmds/lshal/Timeout.h @@ -29,7 +29,7 @@ static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500}; class BackgroundTaskState { public: - BackgroundTaskState(std::function<void(void)> &&func) + explicit BackgroundTaskState(std::function<void(void)> &&func) : mFunc(std::forward<decltype(func)>(func)) {} void notify() { std::unique_lock<std::mutex> lock(mMutex); diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp index 8d7405b89e..fc8d58b3d8 100644 --- a/cmds/lshal/test.cpp +++ b/cmds/lshal/test.cpp @@ -191,7 +191,7 @@ public: // expose protected fields and methods for ListCommand class MockListCommand : public ListCommand { public: - MockListCommand(Lshal* lshal) : ListCommand(*lshal) {} + explicit MockListCommand(Lshal* lshal) : ListCommand(*lshal) {} Status parseArgs(const Arg& arg) { return ListCommand::parseArgs(arg); } Status main(const Arg& arg) { return ListCommand::main(arg); } @@ -308,7 +308,7 @@ static hidl_hash getHashFromId(pid_t serverId) { // Fake service returned by mocked IServiceManager::get. class TestService : public IBase { public: - TestService(pid_t id) : mId(id) {} + explicit TestService(pid_t id) : mId(id) {} hardware::Return<void> getDebugInfo(getDebugInfo_cb cb) override { cb({ mId /* pid */, getPtr(mId), DebugInfo::Architecture::IS_64BIT }); return hardware::Void(); diff --git a/cmds/servicemanager/binder.c b/cmds/servicemanager/binder.c index a2b4da2f69..cf3b1728b6 100644 --- a/cmds/servicemanager/binder.c +++ b/cmds/servicemanager/binder.c @@ -154,9 +154,7 @@ int binder_become_context_manager(struct binder_state *bs) // fallback to original method if (result != 0) { -#ifndef VENDORSERVICEMANAGER android_errorWriteLog(0x534e4554, "121035042"); -#endif result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); } diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c index ca004e96a9..ec3fac538d 100644 --- a/cmds/servicemanager/service_manager.c +++ b/cmds/servicemanager/service_manager.c @@ -77,11 +77,9 @@ static bool check_mac_perms(pid_t spid, const char* sid, uid_t uid, const char * ad.uid = uid; ad.name = name; -#ifndef VENDORSERVICEMANAGER if (sid == NULL) { android_errorWriteLog(0x534e4554, "121035042"); } -#endif int result = selinux_check_access(sid ? sid : lookup_sid, tctx, class, perm, (void *) &ad); allowed = (result == 0); diff --git a/headers/media_plugin/media/drm/DrmAPI.h b/headers/media_plugin/media/drm/DrmAPI.h index aa8bd3d06c..2ed1cca6a9 100644 --- a/headers/media_plugin/media/drm/DrmAPI.h +++ b/headers/media_plugin/media/drm/DrmAPI.h @@ -84,6 +84,7 @@ namespace android { kDrmPluginEventSessionReclaimed, kDrmPluginEventExpirationUpdate, kDrmPluginEventKeysChange, + kDrmPluginEventSessionLostState, }; // Drm keys can be for offline content or for online streaming. diff --git a/include/android/surface_control.h b/include/android/surface_control.h new file mode 100644 index 0000000000..13b630ba57 --- /dev/null +++ b/include/android/surface_control.h @@ -0,0 +1,207 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file surface_control.h + */ + +#ifndef ANDROID_SURFACE_CONTROL_H +#define ANDROID_SURFACE_CONTROL_H + +#include <sys/cdefs.h> + +#include <android/hardware_buffer.h> +#include <android/native_window.h> + +__BEGIN_DECLS + +#if __ANDROID_API__ >= 29 + +struct ASurfaceControl; + +/** + * The SurfaceControl API can be used to provide a heirarchy of surfaces for + * composition to the system compositor. ASurfaceControl represents a content node in + * this heirarchy. + */ +typedef struct ASurfaceControl ASurfaceControl; + +/* + * Creates an ASurfaceControl with either ANativeWindow or an ASurfaceControl as its parent. + * |debug_name| is a debug name associated with this surface. It can be used to + * identify this surface in the SurfaceFlinger's layer tree. It must not be + * null. + * + * The caller takes ownership of the ASurfaceControl returned and must release it + * using ASurfaceControl_release below. + */ +ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* parent, const char* debug_name) + __INTRODUCED_IN(29); + +ASurfaceControl* ASurfaceControl_create(ASurfaceControl* parent, const char* debug_name) + __INTRODUCED_IN(29); + +/** + * Destroys the |surface_control| object. After releasing the ASurfaceControl the caller no longer + * has ownership of the AsurfaceControl. + */ +void ASurfaceControl_destroy(ASurfaceControl* surface_control) __INTRODUCED_IN(29); + +struct ASurfaceTransaction; + +/** + * ASurfaceTransaction is a collection of updates to the surface tree that must + * be applied atomically. + */ +typedef struct ASurfaceTransaction ASurfaceTransaction; + +/** + * The caller takes ownership of the transaction and must release it using + * ASurfaceControl_delete below. + */ +ASurfaceTransaction* ASurfaceTransaction_create() __INTRODUCED_IN(29); + +/** + * Destroys the |transaction| object. + */ +void ASurfaceTransaction_delete(ASurfaceTransaction* transaction) __INTRODUCED_IN(29); + +/** + * Applies the updates accumulated in |transaction|. + * + * Note that the transaction is guaranteed to be applied atomically. The + * transactions which are applied on the same thread are also guaranteed to be + * applied in order. + */ +void ASurfaceTransaction_apply(ASurfaceTransaction* transaction) __INTRODUCED_IN(29); + +/** + * Since the transactions are applied asynchronously, the + * ASurfaceTransaction_OnComplete callback can be used to be notified when a frame + * including the updates in a transaction was presented. + * + * |context| is the optional context provided by the client that is passed into + * the callback. + * |present_fence| is the sync fence that signals when the transaction has been presented. + * The recipient of the callback takes ownership of the present_fence and is responsible for closing + * it. + * + * It is safe to assume that once the present fence singals, that reads for all buffers, + * submitted in previous transactions, which are not in the surface tree after a transaction is + * applied, are finished and the buffers may be reused. + * + * THREADING + * The transaction completed callback can be invoked on any thread. + */ +typedef void (*ASurfaceTransaction_OnComplete)(void* context, int32_t present_fence); + +/** + * Sets the callback that will be invoked when the updates from this transaction + * are presented. For details on the callback semantics and data, see the + * comments on the ASurfaceTransaction_OnComplete declaration above. + */ +void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* transaction, void* context, + ASurfaceTransaction_OnComplete func) __INTRODUCED_IN(29); + +/* Parameter for ASurfaceTransaction_setVisibility */ +enum { + ASURFACE_TRANSACTION_VISIBILITY_HIDE = 0, + ASURFACE_TRANSACTION_VISIBILITY_SHOW = 1, +}; +/** + * Updates the visibility of |surface_control|. If show is set to + * ASURFACE_TRANSACTION_VISIBILITY_HIDE, the |surface_control| and all surfaces in its subtree will + * be hidden. + */ +void ASurfaceTransaction_setVisibility(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, int8_t visibility) + __INTRODUCED_IN(29); + +/** + * Updates the z order index for |surface_control|. Note that the z order for a surface + * is relative to other surfaces which are siblings of this surface. The behavior of sibilings with + * the same z order is undefined. + * + * Z orders may be from MIN_INT32 to MAX_INT32. A layer's default z order index is 0. + */ +void ASurfaceTransaction_setZOrder(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, int32_t z_order) + __INTRODUCED_IN(29); + +/** + * Updates the AHardwareBuffer displayed for |surface_control|. If not -1, the + * fence_fd should be a file descriptor that is signaled when all pending work + * for the buffer is complete and the buffer can be safely read. + * + * The frameworks takes ownership of the |fence_fd| passed and is responsible + * for closing it. + */ +void ASurfaceTransaction_setBuffer(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, AHardwareBuffer* buffer, + int fence_fd = -1) __INTRODUCED_IN(29); + +/** + * |source| the sub-rect within the buffer's content to be rendered inside the surface's area + * The surface's source rect is clipped by the bounds of its current buffer. The source rect's width + * and height must be > 0. + * + * |destination| specifies the rect in the parent's space where this surface will be drawn. The post + * source rect bounds are scaled to fit the destination rect. The surface's destination rect is + * clipped by the bounds of its parent. The destination rect's width and height must be > 0. + * + * |transform| the transform applied after the source rect is applied to the buffer. This parameter + * should be set to 0 for no transform. To specify a transfrom use the NATIVE_WINDOW_TRANSFORM_* + * enum. + */ +void ASurfaceTransaction_setGeometry(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, const ARect& source, + const ARect& destination, int32_t transform) + __INTRODUCED_IN(29); + + +/* Parameter for ASurfaceTransaction_setBufferTransparency */ +enum { + ASURFACE_TRANSACTION_TRANSPARENCY_TRANSPARENT = 0, + ASURFACE_TRANSACTION_TRANSPARENCY_TRANSLUCENT = 1, + ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE = 2, +}; +/** + * Updates whether the content for the buffer associated with this surface is + * completely opaque. If true, every pixel of content inside the buffer must be + * opaque or visual errors can occur. + */ +void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, int8_t transparency) + __INTRODUCED_IN(29); + +/** + * Updates the region for the content on this surface updated in this + * transaction. If unspecified, the complete surface is assumed to be damaged. + */ +void ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, const ARect rects[], + uint32_t count) __INTRODUCED_IN(29); + +#endif // __ANDROID_API__ >= 29 + +__END_DECLS + +#endif // ANDROID_SURFACE_CONTROL_H diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 8df83f1afe..1d4e234558 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -23,7 +23,9 @@ #include <binder/BpBinder.h> #include <binder/TextOutput.h> +#include <android-base/macros.h> #include <cutils/sched_policy.h> +#include <utils/CallStack.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <utils/threads.h> @@ -661,6 +663,16 @@ status_t IPCThreadState::transact(int32_t handle, } if ((flags & TF_ONE_WAY) == 0) { + if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) { + if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) { + ALOGE("Process making non-oneway call but is restricted."); + CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(), + ANDROID_LOG_ERROR); + } else /* FATAL_IF_NOT_ONEWAY */ { + LOG_ALWAYS_FATAL("Process may not make oneway calls."); + } + } + #if 0 if (code == 4) { // relayout ALOGI(">>>>>> CALLING transaction 4"); @@ -783,7 +795,8 @@ IPCThreadState::IPCThreadState() mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mStrictModePolicy(0), - mLastTransactionBinderFlags(0) + mLastTransactionBinderFlags(0), + mCallRestriction(mProcess->mCallRestriction) { pthread_setspecific(gTLS, this); clearCaller(); diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 53f8dddfe1..3798b61ab9 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -234,6 +234,12 @@ ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) return count; } +void ProcessState::setCallRestriction(CallRestriction restriction) { + LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull(), "Call restrictions must be set before the threadpool is started."); + + mCallRestriction = restriction; +} + ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) { const size_t N=mHandleToObject.size(); @@ -426,6 +432,7 @@ ProcessState::ProcessState(const char *driver) , mBinderContextUserData(nullptr) , mThreadPoolStarted(false) , mThreadPoolSeq(1) + , mCallRestriction(CallRestriction::NONE) { if (mDriverFD >= 0) { // mmap the binder, providing a chunk of virtual address space to receive transactions. diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index 26e8c0b599..a6b0f7e218 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -183,6 +183,8 @@ private: int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; IPCThreadStateBase *mIPCThreadStateBase; + + ProcessState::CallRestriction mCallRestriction; }; }; // namespace android diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h index 3712c84a58..224cb36807 100644 --- a/libs/binder/include/binder/ProcessState.h +++ b/libs/binder/include/binder/ProcessState.h @@ -77,6 +77,18 @@ public: ssize_t getKernelReferences(size_t count, uintptr_t* buf); + enum class CallRestriction { + // all calls okay + NONE, + // log when calls are blocking + ERROR_IF_NOT_ONEWAY, + // abort process on blocking calls + FATAL_IF_NOT_ONEWAY, + }; + // Sets calling restrictions for all transactions in this process. This must be called + // before any threads are spawned. + void setCallRestriction(CallRestriction restriction); + private: friend class IPCThreadState; @@ -123,6 +135,8 @@ private: String8 mRootDir; bool mThreadPoolStarted; volatile int32_t mThreadPoolSeq; + + CallRestriction mCallRestriction; }; }; // namespace android diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp index c70f18823c..052e650bec 100644 --- a/libs/ui/BufferHubBuffer.cpp +++ b/libs/ui/BufferHubBuffer.cpp @@ -181,7 +181,7 @@ int BufferHubBuffer::initWithBufferTraits(const BufferTraits& bufferTraits) { } // Import the metadata. Dup since hidl_handle owns the fd - unique_fd ashmemFd(dup(bufferTraits.bufferInfo->data[0])); + unique_fd ashmemFd(fcntl(bufferTraits.bufferInfo->data[0], F_DUPFD_CLOEXEC, 0)); mMetadata = BufferHubMetadata::Import(std::move(ashmemFd)); if (!mMetadata.IsValid()) { diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index efea408954..9af189ae2b 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -3131,7 +3131,9 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input for (size_t i = 0; i < newHandles.size(); i++) { const sp<InputWindowHandle>& windowHandle = newHandles.itemAt(i); - if (windowHandle->getInfo()->hasFocus && windowHandle->getInfo()->visible) { + // Set newFocusedWindowHandle to the top most focused window instead of the last one + if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus + && windowHandle->getInfo()->visible) { newFocusedWindowHandle = windowHandle; } if (windowHandle == mLastHoverWindowHandle) { diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 7553a6861f..3edec40e4e 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -515,7 +515,7 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) { sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT); - // Set focus application. + // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); // Expect one focus window exist in display. @@ -533,6 +533,32 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) { windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE); } +TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) { + sp<FakeApplicationHandle> application = new FakeApplicationHandle(); + sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top", + ADISPLAY_ID_DEFAULT); + sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second", + ADISPLAY_ID_DEFAULT); + + // Set focused application. + mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); + + // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first) + windowTop->setFocus(); + windowSecond->setFocus(); + Vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.add(windowTop); + inputWindowHandles.add(windowSecond); + + mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); + ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) + << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; + + // Top focused window should receive event. + windowTop->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE); + windowSecond->assertNoEvents(); +} + TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 3dee0c0f02..5b3bbca49f 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -55,6 +55,7 @@ cc_defaults { "libui", "libinput", "libutils", + "libutilscallstack", ], static_libs: [ "libcompositionengine", diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4eafeac293..164a3a6a7e 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -624,16 +624,19 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT * minimal value)? Or, we could make GL behave like HWC -- but this feel * like more of a hack. */ - const Rect bounds{computeBounds()}; // Rounds from FloatRect - Rect win = bounds; - const int bufferWidth = getBufferSize(s).getWidth(); - const int bufferHeight = getBufferSize(s).getHeight(); - - const float left = float(win.left) / float(bufferWidth); - const float top = float(win.top) / float(bufferHeight); - const float right = float(win.right) / float(bufferWidth); - const float bottom = float(win.bottom) / float(bufferHeight); + // Convert to Rect so that bounds are clipped to integers. + const Rect win{computeCrop(Rect::INVALID_RECT)}; + // computeCrop() returns the cropping rectangle in buffer space, so we + // shouldn't use getBufferSize() since that may return a rectangle specified + // in layer space. Otherwise we may compute incorrect texture coordinates. + const float bufWidth = float(mActiveBuffer->getWidth()); + const float bufHeight = float(mActiveBuffer->getHeight()); + + const float left = win.left / bufWidth; + const float top = win.top / bufHeight; + const float right = win.right / bufWidth; + const float bottom = win.bottom / bufHeight; // TODO: we probably want to generate the texture coords with the mesh // here we assume that we only have 4 vertices diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index d1b1697af8..aecde9fd75 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -39,7 +39,7 @@ public: bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; } protected: - FloatRect computeCrop(const sp<const DisplayDevice>& /*display*/) const override { return {}; } + FloatRect computeCrop(const Rect& /*windowbounds*/) const override { return {}; } }; } // namespace android diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 2d91c68f02..03eafd51b2 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -40,13 +40,12 @@ namespace { class BufferHandle { public: - BufferHandle(const native_handle_t* buffer) - { + explicit BufferHandle(const native_handle_t* buffer) { // nullptr is not a valid handle to HIDL mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0); } - operator const hidl_handle&() const + operator const hidl_handle&() const // NOLINT(google-explicit-constructor) { return mHandle; } @@ -80,7 +79,7 @@ public: } } - operator const hidl_handle&() const + operator const hidl_handle&() const // NOLINT(google-explicit-constructor) { return mHandle; } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 9d0d8d92f2..ba3d2a6adc 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -285,7 +285,7 @@ private: // Composer is a wrapper to IComposer, a proxy to server-side composer. class Composer final : public Hwc2::Composer { public: - Composer(const std::string& serviceName); + explicit Composer(const std::string& serviceName); ~Composer() override; std::vector<IComposer::Capability> getCapabilities() override; @@ -418,7 +418,7 @@ public: private: class CommandWriter : public CommandWriterBase { public: - CommandWriter(uint32_t initialMaxSize); + explicit CommandWriter(uint32_t initialMaxSize); ~CommandWriter() override; void setLayerInfo(uint32_t type, uint32_t appId); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3f2d10a45b..ee49610dfc 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -380,7 +380,7 @@ Rect Layer::getCroppedBufferSize(const State& s) const { return size; } -Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const { +Rect Layer::computeInitialCrop(const Rect& windowBounds) const { // the crop is the area of the window that gets cropped, but not // scaled in any ways. const State& s(getDrawingState()); @@ -391,12 +391,17 @@ Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const { // pixels in the buffer. FloatRect activeCropFloat = computeBounds(); - ui::Transform t = getTransform(); - // Transform to screen space. - activeCropFloat = t.transform(activeCropFloat); - activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect()); - // Back to layer space to work with the content crop. - activeCropFloat = t.inverse().transform(activeCropFloat); + + // If we have valid window boundaries then we need to crop to the window + // boundaries in layer space. + if (windowBounds.isValid()) { + const ui::Transform t = getTransform(); + // Transform to screen space. + activeCropFloat = t.transform(activeCropFloat); + activeCropFloat = activeCropFloat.intersect(windowBounds.toFloatRect()); + // Back to layer space to work with the content crop. + activeCropFloat = t.inverse().transform(activeCropFloat); + } // This needs to be here as transform.transform(Rect) computes the // transformed rect and then takes the bounding box of the result before // returning. This means @@ -426,7 +431,7 @@ void Layer::setupRoundedCornersCropCoordinates(Rect win, cropCoords[3] = vec2(win.right, win.top); } -FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const { +FloatRect Layer::computeCrop(const Rect& windowBounds) const { // the content crop is the area of the content that gets scaled to the // layer's size. This is in buffer space. FloatRect crop = getContentCrop().toFloatRect(); @@ -434,7 +439,7 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const { // In addition there is a WM-specified crop we pull from our drawing state. const State& s(getDrawingState()); - Rect activeCrop = computeInitialCrop(display); + Rect activeCrop = computeInitialCrop(windowBounds); Rect bufferSize = getBufferSize(s); // Transform the window crop to match the buffer coordinate system, diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2e75088a28..7bc7a82d3b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -671,12 +671,22 @@ protected: uint32_t getEffectiveUsage(uint32_t usage) const; - virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const; + // Computes the crop applied to this layer. windowBounds is the boundary of + // layer-stack space, so the cropping rectangle will be clipped to those + // bounds in that space. The crop rectangle is returned in buffer space. If + // windowBounds is invalid, then it is ignored. + virtual FloatRect computeCrop(const Rect& windowBounds) const; + + // See the above method, but pulls the window boundaries from the display. + FloatRect computeCrop(const sp<const DisplayDevice>& display) const { + return computeCrop(display->getViewport()); + } // Compute the initial crop as specified by parent layers and the // SurfaceControl for this layer. Does not include buffer crop from the // IGraphicBufferProducer client, as that should not affect child clipping. // Returns in screen space. - Rect computeInitialCrop(const sp<const DisplayDevice>& display) const; + Rect computeInitialCrop(const Rect& windowBounds) const; + /** * Setup rounded corners coordinates of this layer, taking into account the layer bounds and * crop coordinates, transforming them into layer space. diff --git a/services/surfaceflinger/StartPropertySetThread.h b/services/surfaceflinger/StartPropertySetThread.h index a64c21b21f..bbdcde2809 100644 --- a/services/surfaceflinger/StartPropertySetThread.h +++ b/services/surfaceflinger/StartPropertySetThread.h @@ -33,7 +33,7 @@ class StartPropertySetThread : public Thread { // Any property_set() will block during init stage so need to be offloaded // to this thread. see b/63844978. public: - StartPropertySetThread(bool timestampPropertyValue); + explicit StartPropertySetThread(bool timestampPropertyValue); status_t Start(); private: virtual bool threadLoop(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index bd16d645f1..9eff3c6ef6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -52,6 +52,7 @@ #include <ui/GraphicBufferAllocator.h> #include <ui/PixelFormat.h> #include <ui/UiConfig.h> +#include <utils/CallStack.h> #include <utils/StopWatch.h> #include <utils/String16.h> #include <utils/String8.h> @@ -1935,22 +1936,78 @@ void SurfaceFlinger::setCompositorTimingSnapped(const DisplayStatInfo& stats, getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } +// debug patch for b/119477596 - add stack guards to catch stack +// corruptions and disable clang optimizations. +// The code below is temporary and planned to be removed once stack +// corruptions are found. +#pragma clang optimize off +class StackGuard { +public: + StackGuard(const char* name, const char* func, int line) { + guarders.reserve(MIN_CAPACITY); + guarders.push_back({this, name, func, line}); + validate(); + } + ~StackGuard() { + for (auto i = guarders.end() - 1; i >= guarders.begin(); --i) { + if (i->guard == this) { + guarders.erase(i); + break; + } + } + } + + static void validate() { + for (const auto& guard : guarders) { + if (guard.guard->cookie != COOKIE_VALUE) { + ALOGE("%s:%d: Stack corruption detected at %s", guard.func, guard.line, guard.name); + CallStack stack(LOG_TAG); + abort(); + } + } + } + +private: + uint64_t cookie = COOKIE_VALUE; + static constexpr uint64_t COOKIE_VALUE = 0xc0febebedeadbeef; + static constexpr size_t MIN_CAPACITY = 16; + + struct GuarderElement { + StackGuard* guard; + const char* name; + const char* func; + int line; + }; + + static std::vector<GuarderElement> guarders; +}; +std::vector<StackGuard::GuarderElement> StackGuard::guarders; + +#define DEFINE_STACK_GUARD(__n) StackGuard __n##StackGuard(#__n, __FUNCTION__, __LINE__); + +#define ASSERT_ON_STACK_GUARD() StackGuard::validate(); void SurfaceFlinger::postComposition() { + DEFINE_STACK_GUARD(begin); ATRACE_CALL(); ALOGV("postComposition"); // Release any buffers which were replaced this frame nsecs_t dequeueReadyTime = systemTime(); + DEFINE_STACK_GUARD(dequeueReadyTime); for (auto& layer : mLayersWithQueuedFrames) { layer->releasePendingBuffer(dequeueReadyTime); } + ASSERT_ON_STACK_GUARD(); // |mStateLock| not needed as we are on the main thread const auto display = getDefaultDisplayDeviceLocked(); + DEFINE_STACK_GUARD(display); getBE().mGlCompositionDoneTimeline.updateSignalTimes(); std::shared_ptr<FenceTime> glCompositionDoneFenceTime; + DEFINE_STACK_GUARD(glCompositionDoneFenceTime); + if (display && getHwComposer().hasClientComposition(display->getId())) { glCompositionDoneFenceTime = std::make_shared<FenceTime>(display->getClientTargetAcquireFence()); @@ -1959,13 +2016,17 @@ void SurfaceFlinger::postComposition() glCompositionDoneFenceTime = FenceTime::NO_FENCE; } + ASSERT_ON_STACK_GUARD(); + getBE().mDisplayTimeline.updateSignalTimes(); mPreviousPresentFence = display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE; auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence); + DEFINE_STACK_GUARD(presentFenceTime); getBE().mDisplayTimeline.push(presentFenceTime); DisplayStatInfo stats; + DEFINE_STACK_GUARD(stats); if (mUseScheduler) { mScheduler->getDisplayStatInfo(&stats); } else { @@ -1973,34 +2034,46 @@ void SurfaceFlinger::postComposition() stats.vsyncPeriod = mPrimaryDispSync->getPeriod(); } + ASSERT_ON_STACK_GUARD(); + // We use the mRefreshStartTime which might be sampled a little later than // when we started doing work for this frame, but that should be okay // since updateCompositorTiming has snapping logic. updateCompositorTiming(stats, mRefreshStartTime, presentFenceTime); CompositorTiming compositorTiming; + DEFINE_STACK_GUARD(compositorTiming); + { std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock); + DEFINE_STACK_GUARD(lock); compositorTiming = getBE().mCompositorTiming; + + ASSERT_ON_STACK_GUARD(); } mDrawingState.traverseInZOrder([&](Layer* layer) { bool frameLatched = layer->onPostComposition(display->getId(), glCompositionDoneFenceTime, presentFenceTime, compositorTiming); + DEFINE_STACK_GUARD(frameLatched); if (frameLatched) { recordBufferingStats(layer->getName().string(), layer->getOccupancyHistory(false)); } + ASSERT_ON_STACK_GUARD(); }); if (presentFenceTime->isValid()) { + ASSERT_ON_STACK_GUARD(); if (mUseScheduler) { mScheduler->addPresentFence(presentFenceTime); + ASSERT_ON_STACK_GUARD(); } else { if (mPrimaryDispSync->addPresentFence(presentFenceTime)) { enableHardwareVsync(); } else { disableHardwareVsync(false); } + ASSERT_ON_STACK_GUARD(); } } @@ -2014,61 +2087,86 @@ void SurfaceFlinger::postComposition() } } + ASSERT_ON_STACK_GUARD(); + if (mAnimCompositionPending) { mAnimCompositionPending = false; if (presentFenceTime->isValid()) { mAnimFrameTracker.setActualPresentFence( std::move(presentFenceTime)); + + ASSERT_ON_STACK_GUARD(); } else if (display && getHwComposer().isConnected(*display->getId())) { // The HWC doesn't support present fences, so use the refresh // timestamp instead. const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId()); + DEFINE_STACK_GUARD(presentTime); + mAnimFrameTracker.setActualPresentTime(presentTime); + ASSERT_ON_STACK_GUARD(); } mAnimFrameTracker.advanceFrame(); } + ASSERT_ON_STACK_GUARD(); + mTimeStats->incrementTotalFrames(); if (mHadClientComposition) { mTimeStats->incrementClientCompositionFrames(); } + ASSERT_ON_STACK_GUARD(); + mTimeStats->setPresentFenceGlobal(presentFenceTime); + ASSERT_ON_STACK_GUARD(); + if (display && getHwComposer().isConnected(*display->getId()) && !display->isPoweredOn()) { return; } nsecs_t currentTime = systemTime(); + DEFINE_STACK_GUARD(currentTime); if (mHasPoweredOff) { mHasPoweredOff = false; } else { nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime; + DEFINE_STACK_GUARD(elapsedTime); size_t numPeriods = static_cast<size_t>(elapsedTime / stats.vsyncPeriod); + DEFINE_STACK_GUARD(numPeriods); if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) { getBE().mFrameBuckets[numPeriods] += elapsedTime; } else { getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] += elapsedTime; } getBE().mTotalTime += elapsedTime; + + ASSERT_ON_STACK_GUARD(); } getBE().mLastSwapTime = currentTime; + ASSERT_ON_STACK_GUARD(); { std::lock_guard lock(mTexturePoolMutex); + DEFINE_STACK_GUARD(lock); const size_t refillCount = mTexturePoolSize - mTexturePool.size(); + DEFINE_STACK_GUARD(refillCount); if (refillCount > 0) { const size_t offset = mTexturePool.size(); mTexturePool.resize(mTexturePoolSize); getRenderEngine().genTextures(refillCount, mTexturePool.data() + offset); ATRACE_INT("TexturePoolSize", mTexturePool.size()); } + ASSERT_ON_STACK_GUARD(); } mTransactionCompletedThread.addPresentFence(mPreviousPresentFence); mTransactionCompletedThread.sendCallbacks(); + + ASSERT_ON_STACK_GUARD(); } +#pragma clang optimize on // b/119477596 void SurfaceFlinger::rebuildLayerStacks() { ATRACE_CALL(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index eb7127e2a6..134f9c2531 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -25,53 +25,46 @@ * NOTE: Make sure this file doesn't include anything from <gl/ > or <gl2/ > */ -#include <cutils/compiler.h> #include <cutils/atomic.h> - -#include <utils/Errors.h> -#include <utils/KeyedVector.h> -#include <utils/RefBase.h> -#include <utils/SortedVector.h> -#include <utils/threads.h> -#include <utils/Trace.h> - -#include <ui/FenceTime.h> -#include <ui/PixelFormat.h> -#include <math/mat4.h> - +#include <cutils/compiler.h> +#include <gui/BufferQueue.h> #include <gui/FrameTimestamps.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposerClient.h> #include <gui/LayerState.h> - #include <gui/OccupancyTracker.h> -#include <gui/BufferQueue.h> - #include <hardware/hwcomposer_defs.h> - +#include <layerproto/LayerProtoHeader.h> +#include <math/mat4.h> #include <serviceutils/PriorityDumper.h> - #include <system/graphics.h> +#include <ui/FenceTime.h> +#include <ui/PixelFormat.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/SortedVector.h> +#include <utils/Trace.h> +#include <utils/threads.h> #include "Barrier.h" #include "DisplayDevice.h" +#include "DisplayHardware/HWC2.h" +#include "DisplayHardware/HWComposer.h" +#include "Effects/Daltonizer.h" #include "FrameTracker.h" #include "LayerBE.h" #include "LayerStats.h" #include "LayerVector.h" -#include "SurfaceFlingerFactory.h" -#include "SurfaceInterceptor.h" -#include "SurfaceTracing.h" -#include "TransactionCompletedThread.h" - -#include "DisplayHardware/HWC2.h" -#include "DisplayHardware/HWComposer.h" -#include "Effects/Daltonizer.h" #include "Scheduler/DispSync.h" #include "Scheduler/EventThread.h" #include "Scheduler/MessageQueue.h" #include "Scheduler/Scheduler.h" #include "Scheduler/VSyncModulator.h" +#include "SurfaceFlingerFactory.h" +#include "SurfaceInterceptor.h" +#include "SurfaceTracing.h" +#include "TransactionCompletedThread.h" #include <map> #include <mutex> @@ -82,8 +75,6 @@ #include <unordered_map> #include <utility> -#include <layerproto/LayerProtoHeader.h> - using namespace android::surfaceflinger; namespace android { @@ -148,10 +139,6 @@ public: const std::string mHwcServiceName; // "default" for real use, something else for testing. - // constant members (no synchronization needed for access) - EGLContext mEGLContext; - EGLDisplay mEGLDisplay; - FenceTimeline mGlCompositionDoneTimeline; FenceTimeline mDisplayTimeline; @@ -412,77 +399,74 @@ private: /* ------------------------------------------------------------------------ * IBinder interface */ - virtual status_t onTransact(uint32_t code, const Parcel& data, - Parcel* reply, uint32_t flags); - virtual status_t dump(int fd, const Vector<String16>& args) { return priorityDump(fd, args); } + status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override; + status_t dump(int fd, const Vector<String16>& args) override { return priorityDump(fd, args); } /* ------------------------------------------------------------------------ * ISurfaceComposer interface */ - virtual sp<ISurfaceComposerClient> createConnection(); - virtual sp<IBinder> createDisplay(const String8& displayName, bool secure); - virtual void destroyDisplay(const sp<IBinder>& displayToken); - virtual sp<IBinder> getBuiltInDisplay(int32_t id); - virtual void setTransactionState(const Vector<ComposerState>& state, - const Vector<DisplayState>& displays, uint32_t flags, - const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands); - virtual void bootFinished(); - virtual bool authenticateSurfaceTexture( - const sp<IGraphicBufferProducer>& bufferProducer) const; - virtual status_t getSupportedFrameTimestamps( - std::vector<FrameEvent>* outSupported) const; - virtual sp<IDisplayEventConnection> createDisplayEventConnection( - ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp); - virtual status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer, - const ui::Dataspace reqDataspace, - const ui::PixelFormat reqPixelFormat, Rect sourceCrop, - uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ISurfaceComposer::Rotation rotation); - virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer, - const ui::Dataspace reqDataspace, - const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, - float frameScale, bool childrenOnly); - virtual status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); - virtual status_t getDisplayConfigs(const sp<IBinder>& displayToken, - Vector<DisplayInfo>* configs); - virtual int getActiveConfig(const sp<IBinder>& displayToken); - virtual status_t getDisplayColorModes(const sp<IBinder>& displayToken, - Vector<ui::ColorMode>* configs); - virtual ui::ColorMode getActiveColorMode(const sp<IBinder>& displayToken); - virtual status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode); - virtual void setPowerMode(const sp<IBinder>& displayToken, int mode); - virtual status_t setActiveConfig(const sp<IBinder>& displayToken, int id); - virtual status_t clearAnimationFrameStats(); - virtual status_t getAnimationFrameStats(FrameStats* outStats) const; - virtual status_t getHdrCapabilities(const sp<IBinder>& displayToken, - HdrCapabilities* outCapabilities) const; - virtual status_t enableVSyncInjections(bool enable); - virtual status_t injectVSync(nsecs_t when); - virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const; - virtual status_t getColorManagement(bool* outGetColorManagement) const; + sp<ISurfaceComposerClient> createConnection() override; + sp<IBinder> createDisplay(const String8& displayName, bool secure) override; + void destroyDisplay(const sp<IBinder>& displayToken) override; + sp<IBinder> getBuiltInDisplay(int32_t id) override; + void setTransactionState(const Vector<ComposerState>& state, + const Vector<DisplayState>& displays, uint32_t flags, + const sp<IBinder>& applyToken, + const InputWindowCommands& inputWindowCommands) override; + void bootFinished() override; + bool authenticateSurfaceTexture( + const sp<IGraphicBufferProducer>& bufferProducer) const override; + status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const override; + sp<IDisplayEventConnection> createDisplayEventConnection( + ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp) override; + status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer, + const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + bool useIdentityTransform, ISurfaceComposer::Rotation rotation) override; + status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer, + const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, + const Rect& sourceCrop, float frameScale, bool childrenOnly) override; + status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats) override; + status_t getDisplayConfigs(const sp<IBinder>& displayToken, + Vector<DisplayInfo>* configs) override; + int getActiveConfig(const sp<IBinder>& displayToken) override; + status_t getDisplayColorModes(const sp<IBinder>& displayToken, + Vector<ui::ColorMode>* configs) override; + ui::ColorMode getActiveColorMode(const sp<IBinder>& displayToken) override; + status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode) override; + void setPowerMode(const sp<IBinder>& displayToken, int mode) override; + status_t setActiveConfig(const sp<IBinder>& displayToken, int id) override; + status_t clearAnimationFrameStats() override; + status_t getAnimationFrameStats(FrameStats* outStats) const override; + status_t getHdrCapabilities(const sp<IBinder>& displayToken, + HdrCapabilities* outCapabilities) const override; + status_t enableVSyncInjections(bool enable) override; + status_t injectVSync(nsecs_t when) override; + status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const override; + status_t getColorManagement(bool* outGetColorManagement) const override; status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat, ui::Dataspace* outWideColorGamutDataspace, ui::PixelFormat* outWideColorGamutPixelFormat) const override; - virtual status_t getDisplayedContentSamplingAttributes( - const sp<IBinder>& display, ui::PixelFormat* outFormat, ui::Dataspace* outDataspace, - uint8_t* outComponentMask) const override; - virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable, - uint8_t componentMask, - uint64_t maxFrames) const override; - virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, - uint64_t timestamp, - DisplayedFrameStats* outStats) const override; + status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) const override; + status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable, + uint8_t componentMask, + uint64_t maxFrames) const override; + status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, + uint64_t timestamp, + DisplayedFrameStats* outStats) const override; /* ------------------------------------------------------------------------ * DeathRecipient interface */ - virtual void binderDied(const wp<IBinder>& who); + void binderDied(const wp<IBinder>& who) override; /* ------------------------------------------------------------------------ * RefBase interface */ - virtual void onFirstRef(); + void onFirstRef() override; /* ------------------------------------------------------------------------ * HWC2::ComposerCallback / HWComposer::EventHandler interface diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 991ea36a3c..ef6999d7b0 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -302,7 +302,7 @@ public: void expectChildColor(uint32_t x, uint32_t y) { checkPixel(x, y, 200, 200, 200); } - ScreenCapture(const sp<GraphicBuffer>& outBuffer) : mOutBuffer(outBuffer) { + explicit ScreenCapture(const sp<GraphicBuffer>& outBuffer) : mOutBuffer(outBuffer) { mOutBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&mPixels)); } diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp index 973156a7c4..eeb6efe576 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp @@ -81,7 +81,7 @@ public: class DelayedEventGenerator { public: - DelayedEventGenerator(std::function<void()> onTimerExpired) + explicit DelayedEventGenerator(std::function<void()> onTimerExpired) : mOnTimerExpired(onTimerExpired), mThread([this]() { loop(); }) {} ~DelayedEventGenerator() { diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerService.h b/services/surfaceflinger/tests/fakehwc/FakeComposerService.h index c439b7e3b2..a3fb8a6248 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerService.h +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerService.h @@ -26,7 +26,7 @@ namespace sftest { class FakeComposerService : public IComposer { public: - FakeComposerService(android::sp<ComposerClient>& client); + explicit FakeComposerService(android::sp<ComposerClient>& client); virtual ~FakeComposerService(); Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h index 1258a970c7..7d20d3c075 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h @@ -100,10 +100,7 @@ public: */ class TransactionScope : public android::SurfaceComposerClient::Transaction { public: - TransactionScope(FakeComposerClient& composer) : - Transaction(), - mComposer(composer) { - } + explicit TransactionScope(FakeComposerClient& composer) : Transaction(), mComposer(composer) {} ~TransactionScope() { int frameCount = mComposer.getFrameCount(); diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h index d7082f3cb5..06ae314899 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h @@ -171,7 +171,7 @@ class Hwc2TestColor; class Hwc2TestBlendMode : public Hwc2TestProperty<hwc2_blend_mode_t> { public: - Hwc2TestBlendMode(Hwc2TestCoverage coverage); + explicit Hwc2TestBlendMode(Hwc2TestCoverage coverage); std::string dump() const override; @@ -192,8 +192,8 @@ protected: class Hwc2TestColor : public Hwc2TestProperty<hwc_color_t> { public: - Hwc2TestColor(Hwc2TestCoverage coverage, - hwc2_blend_mode_t blendMode = HWC2_BLEND_MODE_NONE); + explicit Hwc2TestColor(Hwc2TestCoverage coverage, + hwc2_blend_mode_t blendMode = HWC2_BLEND_MODE_NONE); std::string dump() const override; @@ -217,7 +217,7 @@ protected: class Hwc2TestComposition : public Hwc2TestProperty<hwc2_composition_t> { public: - Hwc2TestComposition(Hwc2TestCoverage coverage); + explicit Hwc2TestComposition(Hwc2TestCoverage coverage); std::string dump() const override; @@ -232,7 +232,7 @@ protected: class Hwc2TestDataspace : public Hwc2TestProperty<android::ui::Dataspace> { public: - Hwc2TestDataspace(Hwc2TestCoverage coverage); + explicit Hwc2TestDataspace(Hwc2TestCoverage coverage); std::string dump() const override; @@ -248,7 +248,7 @@ class Hwc2TestVirtualBuffer; class Hwc2TestDisplayDimension : public Hwc2TestProperty<UnsignedArea> { public: - Hwc2TestDisplayDimension(Hwc2TestCoverage coverage); + explicit Hwc2TestDisplayDimension(Hwc2TestCoverage coverage); std::string dump() const; @@ -291,7 +291,7 @@ protected: class Hwc2TestPlaneAlpha : public Hwc2TestProperty<float> { public: - Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage); + explicit Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage); std::string dump() const override; @@ -306,7 +306,7 @@ protected: class Hwc2TestSourceCrop : public Hwc2TestProperty<hwc_frect_t> { public: - Hwc2TestSourceCrop(Hwc2TestCoverage coverage, const Area& bufferArea = {0, 0}); + explicit Hwc2TestSourceCrop(Hwc2TestCoverage coverage, const Area& bufferArea = {0, 0}); std::string dump() const override; @@ -330,7 +330,7 @@ protected: class Hwc2TestSurfaceDamage : public Hwc2TestProperty<hwc_region_t> { public: - Hwc2TestSurfaceDamage(Hwc2TestCoverage coverage); + explicit Hwc2TestSurfaceDamage(Hwc2TestCoverage coverage); ~Hwc2TestSurfaceDamage(); std::string dump() const override; @@ -356,7 +356,7 @@ protected: class Hwc2TestTransform : public Hwc2TestProperty<hwc_transform_t> { public: - Hwc2TestTransform(Hwc2TestCoverage coverage); + explicit Hwc2TestTransform(Hwc2TestCoverage coverage); std::string dump() const override; diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h index 10c8ef0f1c..5a74a6c104 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h @@ -29,7 +29,7 @@ class Hwc2TestVirtualDisplay { public: - Hwc2TestVirtualDisplay(Hwc2TestCoverage coverage); + explicit Hwc2TestVirtualDisplay(Hwc2TestCoverage coverage); std::string dump() const; |