Merge "Remove BufferHubBuffer:Poll function"
diff --git a/cmds/atrace/atrace_userdebug.rc b/cmds/atrace/atrace_userdebug.rc
index 5c28c9d..6c86c21 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 909bdd7..6596fa2 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -98,11 +98,10 @@
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 @@
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 1736ae8..1705317 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -42,8 +42,8 @@
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 ba3e290..d24c953 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -25,8 +25,6 @@
* {@hide}
*/
interface IDumpstate {
-
-
// TODO: remove method once startBugReport is used by Shell.
/*
* Sets the listener for this dumpstate progress.
@@ -69,6 +67,6 @@
* @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 030d69d..2966c86 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
@@ -22,18 +22,48 @@
* {@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 47c4f62..4e5d68d 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1881,8 +1881,9 @@
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 @@
}
// 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 @@
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 @@
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 @@
}
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 7ac25e4..529111e 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -342,9 +342,11 @@
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 @@
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 61a5ef5..c57775f 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -53,6 +53,19 @@
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 fcf9371..98ee1b0 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -59,6 +59,10 @@
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 4f128ab..e19e3f7 100644
--- a/cmds/lshal/Command.h
+++ b/cmds/lshal/Command.h
@@ -27,7 +27,7 @@
// 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 6e12008..3c3f56f 100644
--- a/cmds/lshal/DebugCommand.h
+++ b/cmds/lshal/DebugCommand.h
@@ -31,7 +31,7 @@
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 cc709f8..da0cba6 100644
--- a/cmds/lshal/HelpCommand.h
+++ b/cmds/lshal/HelpCommand.h
@@ -31,7 +31,7 @@
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 3f7321d..85195fc 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -57,7 +57,7 @@
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 ab37a04..737d3a2 100644
--- a/cmds/lshal/NullableOStream.h
+++ b/cmds/lshal/NullableOStream.h
@@ -25,8 +25,8 @@
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 @@
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 7294b0a..601b7e2 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -149,7 +149,7 @@
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 91d522a..301b4bd 100644
--- a/cmds/lshal/TextTable.h
+++ b/cmds/lshal/TextTable.h
@@ -33,11 +33,11 @@
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 58119a6..46d8177 100644
--- a/cmds/lshal/Timeout.h
+++ b/cmds/lshal/Timeout.h
@@ -29,7 +29,7 @@
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 8d7405b..fc8d58b 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -191,7 +191,7 @@
// 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 @@
// 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 a2b4da2..cf3b172 100644
--- a/cmds/servicemanager/binder.c
+++ b/cmds/servicemanager/binder.c
@@ -154,9 +154,7 @@
// 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 ca004e9..ec3fac5 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -77,11 +77,9 @@
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 aa8bd3d..2ed1cca 100644
--- a/headers/media_plugin/media/drm/DrmAPI.h
+++ b/headers/media_plugin/media/drm/DrmAPI.h
@@ -84,6 +84,7 @@
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 0000000..13b630b
--- /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 8df83f1..1d4e234 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 @@
}
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 @@
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 53f8ddd..3798b61 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -234,6 +234,12 @@
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 @@
, 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 26e8c0b..a6b0f7e 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -183,6 +183,8 @@
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 3712c84..224cb36 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -77,6 +77,18 @@
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 @@
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 87314ec..6310f29 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -181,7 +181,7 @@
}
// 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/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index ad49cd6..a40443d 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -216,7 +216,7 @@
stream << " ";
stream << std::setw(10) << "State";
stream << " ";
- stream << std::setw(10) << "Index";
+ stream << std::setw(8) << "Index";
stream << std::endl;
for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) {
@@ -251,6 +251,7 @@
stream << " ";
stream << "0x" << std::hex << std::setfill('0');
stream << std::setw(8) << /*State=*/state;
+ stream << std::dec << std::setfill(' ');
stream << " ";
stream << std::setw(8) << /*Index=*/index;
stream << std::endl;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 3dee0c0..5b3bbca 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -55,6 +55,7 @@
"libui",
"libinput",
"libutils",
+ "libutilscallstack",
],
static_libs: [
"libcompositionengine",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 4eafeac..164a3a6 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -624,16 +624,19 @@
* 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();
+ // 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 = 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);
+ 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 d1b1697..aecde9f 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -39,7 +39,7 @@
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 2d91c68..03eafd5 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -40,13 +40,12 @@
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 @@
}
}
- 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 9d0d8d9..ba3d2a6 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -285,7 +285,7 @@
// 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 @@
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 3f2d10a..ee49610 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -380,7 +380,7 @@
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 @@
// 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 @@
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 @@
// 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 2e75088..7bc7a82 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -671,12 +671,22 @@
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 a64c21b..bbdcde2 100644
--- a/services/surfaceflinger/StartPropertySetThread.h
+++ b/services/surfaceflinger/StartPropertySetThread.h
@@ -33,7 +33,7 @@
// 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 bd16d64..9eff3c6 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 @@
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 @@
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 @@
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 @@
}
}
+ 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 eb7127e..134f9c2 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 @@
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 @@
/* ------------------------------------------------------------------------
* 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 991ea36..ef6999d 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -302,7 +302,7 @@
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 973156a..eeb6efe 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
@@ -81,7 +81,7 @@
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 c439b7e..a3fb8a6 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerService.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerService.h
@@ -26,7 +26,7 @@
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 1258a97..7d20d3c 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h
@@ -100,10 +100,7 @@
*/
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 d7082f3..06ae314 100644
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h
+++ b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h
@@ -171,7 +171,7 @@
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 @@
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 @@
class Hwc2TestComposition : public Hwc2TestProperty<hwc2_composition_t> {
public:
- Hwc2TestComposition(Hwc2TestCoverage coverage);
+ explicit Hwc2TestComposition(Hwc2TestCoverage coverage);
std::string dump() const override;
@@ -232,7 +232,7 @@
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 Hwc2TestDisplayDimension : public Hwc2TestProperty<UnsignedArea> {
public:
- Hwc2TestDisplayDimension(Hwc2TestCoverage coverage);
+ explicit Hwc2TestDisplayDimension(Hwc2TestCoverage coverage);
std::string dump() const;
@@ -291,7 +291,7 @@
class Hwc2TestPlaneAlpha : public Hwc2TestProperty<float> {
public:
- Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage);
+ explicit Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage);
std::string dump() const override;
@@ -306,7 +306,7 @@
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 @@
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 @@
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 10c8ef0..5a74a6c 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;