Merge changes Iee2984f7,I18a3fd8a
* changes:
Fix logic error in atrace when detecting available categories.
Add several more tracepoints to the memory category in atrace
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 2d780f5..73360a3 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,17 @@
+[Builtin Hooks]
+clang_format = true
+
+[Builtin Hooks Options]
+# Only turn on clang-format check for the following subfolders.
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+ libs/binder/ndk/
+ libs/graphicsenv/
+ libs/gui/
+ libs/ui/
+ libs/vr/
+ services/surfaceflinger/
+ services/vr/
+
[Hook Scripts]
owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
installd_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/installd/"
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 0ee6c3a..849eb44 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -108,7 +108,8 @@
bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_REMOTE &&
bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WEAR &&
bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_TELEPHONY &&
- bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WIFI) {
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WIFI &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_DEFAULT) {
return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
StringPrintf("Invalid bugreport mode: %d", bugreport_mode));
}
@@ -137,6 +138,7 @@
dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str());
dprintf(fd, "version: %s\n", ds_.version_.c_str());
dprintf(fd, "bugreport_dir: %s\n", ds_.bugreport_dir_.c_str());
+ dprintf(fd, "bugreport_internal_dir_: %s\n", ds_.bugreport_internal_dir_.c_str());
dprintf(fd, "screenshot_path: %s\n", ds_.screenshot_path_.c_str());
dprintf(fd, "log_path: %s\n", ds_.log_path_.c_str());
dprintf(fd, "tmp_path: %s\n", ds_.tmp_path_.c_str());
diff --git a/cmds/dumpstate/README.md b/cmds/dumpstate/README.md
index d5b2953..6ac17d8 100644
--- a/cmds/dumpstate/README.md
+++ b/cmds/dumpstate/README.md
@@ -26,6 +26,18 @@
mmm -j frameworks/native/cmds/dumpstate && adb push ${OUT}/system/bin/dumpstate system/bin && adb shell am bug-report
```
+Make sure that the device is remounted before running the above command.
+* If you're working with `userdebug` variant, you may need to run the following to remount your device:
+
+ ```
+ adb root && adb remount -R && adb wait-for-device && adb root && adb remount
+ ```
+* If you're working with `eng` variant, you may need to run the following to remount your device:
+
+ ```
+ adb root && adb remount
+ ```
+
## To build, deploy, and run unit tests
First create `/data/nativetest64`:
@@ -37,13 +49,13 @@
Then run:
```
-mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest/dumpstate_test/dumpstate_test
+mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest64/dumpstate_test/dumpstate_test
```
And to run just one test (for example, `DumpstateTest.RunCommandNoArgs`):
```
-mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest/dumpstate_test/dumpstate_test --gtest_filter=DumpstateTest.RunCommandNoArgs
+mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest64/dumpstate_test/dumpstate_test --gtest_filter=DumpstateTest.RunCommandNoArgs
```
## To take quick bugreports
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index 9e59f58..617eab3 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -40,7 +40,7 @@
boolean getSectionDetails);
// These modes encapsulate a set of run time options for generating bugreports.
- // A zipped bugreport; default mode.
+ // Takes a bugreport without user interference.
const int BUGREPORT_MODE_FULL = 0;
// Interactive bugreport, i.e. triggered by the user.
@@ -58,6 +58,9 @@
// Bugreport limited to only wifi info.
const int BUGREPORT_MODE_WIFI = 5;
+ // Default mode.
+ const int BUGREPORT_MODE_DEFAULT = 6;
+
/*
* Starts a bugreport in the background.
*/
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 026c260..59a0047 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -82,6 +82,7 @@
using android::TIMED_OUT;
using android::UNKNOWN_ERROR;
using android::Vector;
+using android::base::StringPrintf;
using android::os::dumpstate::CommandOptions;
using android::os::dumpstate::DumpFileToFd;
using android::os::dumpstate::DumpstateSectionReporter;
@@ -121,6 +122,69 @@
// TODO: temporary variables and functions used during C++ refactoring
static Dumpstate& ds = Dumpstate::GetInstance();
+
+namespace android {
+namespace os {
+namespace {
+
+static int Open(std::string path, int flags, mode_t mode = 0) {
+ int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
+ if (fd == -1) {
+ MYLOGE("open(%s, %s)\n", path.c_str(), strerror(errno));
+ }
+ return fd;
+}
+
+static int OpenForWrite(std::string path) {
+ return Open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+}
+
+static int OpenForRead(std::string path) {
+ return Open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
+}
+
+bool CopyFile(int in_fd, int out_fd) {
+ char buf[4096];
+ ssize_t byte_count;
+ while ((byte_count = TEMP_FAILURE_RETRY(read(in_fd, buf, sizeof(buf)))) > 0) {
+ if (!android::base::WriteFully(out_fd, buf, byte_count)) {
+ return false;
+ }
+ }
+ return (byte_count != -1);
+}
+
+static bool CopyFileToFd(const std::string& input_file, int out_fd) {
+ MYLOGD("Going to copy bugreport file (%s) to %d\n", ds.path_.c_str(), out_fd);
+
+ // Obtain a handle to the source file.
+ android::base::unique_fd in_fd(OpenForRead(input_file));
+ if (out_fd != -1 && in_fd.get() != -1) {
+ if (CopyFile(in_fd.get(), out_fd)) {
+ return true;
+ }
+ MYLOGE("Failed to copy zip file: %s\n", strerror(errno));
+ }
+ return false;
+}
+
+static bool CopyFileToFile(const std::string& input_file, const std::string& output_file) {
+ if (input_file == output_file) {
+ MYLOGD("Skipping copying bugreport file since the destination is the same (%s)\n",
+ output_file.c_str());
+ return false;
+ }
+
+ MYLOGD("Going to copy bugreport file (%s) to %s\n", input_file.c_str(), output_file.c_str());
+ android::base::unique_fd out_fd(OpenForWrite(output_file));
+ return CopyFileToFd(input_file, out_fd.get());
+}
+
+} // namespace
+} // namespace os
+} // namespace android
+
static int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
const CommandOptions& options = CommandOptions::DEFAULT) {
return ds.RunCommand(title, fullCommand, options);
@@ -137,8 +201,6 @@
// Relative directory (inside the zip) for all files copied as-is into the bugreport.
static const std::string ZIP_ROOT_DIR = "FS";
-// Must be hardcoded because dumpstate HAL implementation need SELinux access to it
-static const std::string kDumpstateBoardPath = "/bugreports/";
static const std::string kProtoPath = "proto/";
static const std::string kProtoExt = ".proto";
static const std::string kDumpstateBoardFiles[] = {
@@ -1145,7 +1207,7 @@
return !isalnum(c) &&
std::string("@-_:.").find(c) == std::string::npos;
}, '_');
- const std::string path = kDumpstateBoardPath + "lshal_debug_" + cleanName;
+ const std::string path = ds.bugreport_internal_dir_ + "/lshal_debug_" + cleanName;
{
auto fd = android::base::unique_fd(
@@ -1523,7 +1585,8 @@
std::vector<std::string> paths;
std::vector<android::base::ScopeGuard<std::function<void()>>> remover;
for (int i = 0; i < NUM_OF_DUMPS; i++) {
- paths.emplace_back(kDumpstateBoardPath + kDumpstateBoardFiles[i]);
+ paths.emplace_back(StringPrintf("%s/%s", ds.bugreport_internal_dir_.c_str(),
+ kDumpstateBoardFiles[i].c_str()));
remover.emplace_back(android::base::make_scope_guard(std::bind(
[](std::string path) {
if (remove(path.c_str()) != 0 && errno != ENOENT) {
@@ -1681,7 +1744,8 @@
MYLOGE("Failed to add dumpstate log to .zip file\n");
return false;
}
- // ... and re-opens it for further logging.
+ // TODO: Should truncate the existing file.
+ // ... and re-open it for further logging.
redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()));
fprintf(stderr, "\n");
@@ -1764,17 +1828,30 @@
// clang-format on
}
+static void MaybeResolveSymlink(std::string* path) {
+ std::string resolved_path;
+ if (android::base::Readlink(*path, &resolved_path)) {
+ *path = resolved_path;
+ }
+}
+
/*
* Prepares state like filename, screenshot path, etc in Dumpstate. Also initializes ZipWriter
* if we are writing zip files and adds the version file.
*/
static void PrepareToWriteToFile() {
- ds.bugreport_dir_ = dirname(ds.options_->use_outfile.c_str());
+ MaybeResolveSymlink(&ds.bugreport_internal_dir_);
+
+ std::string base_name_part1 = "bugreport";
+ if (!ds.options_->use_outfile.empty()) {
+ ds.bugreport_dir_ = dirname(ds.options_->use_outfile.c_str());
+ base_name_part1 = basename(ds.options_->use_outfile.c_str());
+ }
+
std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
std::string device_name = android::base::GetProperty("ro.product.name", "UNKNOWN_DEVICE");
ds.base_name_ =
- android::base::StringPrintf("%s-%s-%s", basename(ds.options_->use_outfile.c_str()),
- device_name.c_str(), build_id.c_str());
+ StringPrintf("%s-%s-%s", base_name_part1.c_str(), device_name.c_str(), build_id.c_str());
if (ds.options_->do_add_date) {
char date[80];
strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
@@ -1795,15 +1872,18 @@
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();
MYLOGD(
"Bugreport dir: %s\n"
+ "Internal Bugreport dir: %s\n"
"Base name: %s\n"
"Suffix: %s\n"
"Log path: %s\n"
"Temporary path: %s\n"
"Screenshot path: %s\n",
- ds.bugreport_dir_.c_str(), ds.base_name_.c_str(), ds.name_.c_str(), ds.log_path_.c_str(),
- ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
+ destination.c_str(), ds.bugreport_internal_dir_.c_str(), ds.base_name_.c_str(),
+ ds.name_.c_str(), ds.log_path_.c_str(), ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
if (ds.options_->do_zip_file) {
ds.path_ = ds.GetPath(".zip");
@@ -1858,6 +1938,30 @@
do_text_file = true;
} else {
do_text_file = false;
+ // If the user has changed the suffix, we need to change the zip file name.
+ std::string new_path = ds.GetPath(".zip");
+ if (ds.path_ != new_path) {
+ MYLOGD("Renaming zip file from %s to %s\n", ds.path_.c_str(), new_path.c_str());
+ if (rename(ds.path_.c_str(), new_path.c_str())) {
+ MYLOGE("rename(%s, %s): %s\n", ds.path_.c_str(), new_path.c_str(),
+ strerror(errno));
+ } else {
+ ds.path_ = new_path;
+ }
+ }
+ // 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);
+ } else {
+ ds.final_path_ = ds.GetPath(ds.bugreport_dir_, ".zip");
+ copy_succeeded = android::os::CopyFileToFile(ds.path_, ds.final_path_);
+ }
+ if (copy_succeeded) {
+ if (remove(ds.path_.c_str())) {
+ MYLOGE("remove(%s): %s", ds.path_.c_str(), strerror(errno));
+ }
+ }
}
}
if (do_text_file) {
@@ -1882,8 +1986,9 @@
/* Broadcasts that we are done with the bugreport */
static void SendBugreportFinishedBroadcast() {
- if (!ds.path_.empty()) {
- MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
+ // TODO(b/111441001): use callback instead of broadcast.
+ if (!ds.final_path_.empty()) {
+ MYLOGI("Final bugreport path: %s\n", ds.final_path_.c_str());
// clang-format off
std::vector<std::string> am_args = {
@@ -1891,7 +1996,7 @@
"--ei", "android.intent.extra.ID", std::to_string(ds.id_),
"--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
"--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
- "--es", "android.intent.extra.BUGREPORT", ds.path_,
+ "--es", "android.intent.extra.BUGREPORT", ds.final_path_,
"--es", "android.intent.extra.DUMPSTATE_LOG", ds.log_path_
};
// clang-format on
@@ -1913,7 +2018,7 @@
if (ds.options_->is_remote_mode) {
am_args.push_back("--es");
am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
- am_args.push_back(SHA256_file_hash(ds.path_));
+ am_args.push_back(SHA256_file_hash(ds.final_path_));
SendBroadcast("com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
} else {
SendBroadcast("com.android.internal.intent.action.BUGREPORT_FINISHED", am_args);
@@ -1937,10 +2042,13 @@
return "BUGREPORT_TELEPHONY";
case Dumpstate::BugreportMode::BUGREPORT_WIFI:
return "BUGREPORT_WIFI";
+ case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+ return "BUGREPORT_DEFAULT";
}
}
static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options) {
+ options->extra_options = ModeToString(mode);
switch (mode) {
case Dumpstate::BugreportMode::BUGREPORT_FULL:
options->do_broadcast = true;
@@ -1977,12 +2085,14 @@
options->do_fb = true;
options->do_broadcast = true;
break;
+ case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+ break;
}
}
static Dumpstate::BugreportMode getBugreportModeFromProperty() {
- // If the system property is not set, it's assumed to be a full bugreport.
- Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_FULL;
+ // If the system property is not set, it's assumed to be a default bugreport.
+ Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
std::string extra_options = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
if (!extra_options.empty()) {
@@ -1990,6 +2100,8 @@
// Currently, it contains the type of the requested bugreport.
if (extra_options == "bugreportplus") {
mode = Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE;
+ } else if (extra_options == "bugreportfull") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_FULL;
} else if (extra_options == "bugreportremote") {
mode = Dumpstate::BugreportMode::BUGREPORT_REMOTE;
} else if (extra_options == "bugreportwear") {
@@ -2043,6 +2155,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("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());
@@ -2108,8 +2221,13 @@
}
bool Dumpstate::DumpOptions::ValidateOptions() const {
- if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast)
- && use_outfile.empty()) {
+ if (fd != -1 && !do_zip_file) {
+ return false;
+ }
+
+ bool has_out_file_options = !use_outfile.empty() || fd != -1;
+ if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast) &&
+ !has_out_file_options) {
return false;
}
@@ -2131,10 +2249,31 @@
options_ = std::move(options);
}
+/*
+ * Dumps relevant information to a bugreport based on the given options.
+ *
+ * The bugreport can be dumped to a file or streamed to a socket.
+ *
+ * How dumping to file works:
+ * stdout is redirected to a temporary file. This will later become the main bugreport entry.
+ * stderr is redirected a log file.
+ *
+ * The temporary bugreport is then populated via printfs, dumping contents of files and
+ * output of commands to stdout.
+ *
+ * If zipping, the temporary bugreport file is added to the zip archive. Else it's renamed to final
+ * text file.
+ *
+ * If zipping, a bunch of other files and dumps also get added to the zip archive. The log file also
+ * gets added to the archive.
+ *
+ * Bugreports are first generated in a local directory and later copied to the caller's fd or
+ * directory.
+ */
Dumpstate::RunStatus Dumpstate::Run() {
+ LogDumpOptions(*options_);
if (!options_->ValidateOptions()) {
MYLOGE("Invalid options specified\n");
- LogDumpOptions(*options_);
return RunStatus::INVALID_INPUT;
}
/* set as high priority, and protect from OOM killer */
@@ -2174,9 +2313,9 @@
// TODO: temporarily set progress until it's part of the Dumpstate constructor
std::string stats_path =
- is_redirecting ? android::base::StringPrintf("%s/dumpstate-stats.txt",
- dirname(options_->use_outfile.c_str()))
- : "";
+ is_redirecting
+ ? android::base::StringPrintf("%s/dumpstate-stats.txt", bugreport_internal_dir_.c_str())
+ : "";
progress_.reset(new Progress(stats_path));
/* gets the sequential id */
@@ -2272,13 +2411,18 @@
int dup_stdout_fd;
int dup_stderr_fd;
if (is_redirecting) {
+ // Redirect stderr to log_path_ for debugging.
TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()));
if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) {
MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(),
strerror(errno));
}
+
+ // Redirect stdout to tmp_path_. This is the main bugreport entry and will be
+ // moved into zip file later, if zipping.
TEMP_FAILURE_RETRY(dup_stdout_fd = dup(fileno(stdout)));
+ // TODO: why not write to a file instead of stdout to overcome this problem?
/* TODO: rather than generating a text file now and zipping it later,
it would be more efficient to redirect stdout to the zip entry
directly, but the libziparchive doesn't support that option yet. */
@@ -2353,7 +2497,7 @@
return RunStatus::OK;
}
-/* Main entry point for dumpstate. */
+/* Main entry point for dumpstate binary. */
int run_main(int argc, char* argv[]) {
std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
Dumpstate::RunStatus status = options->Initialize(argc, argv);
@@ -2365,7 +2509,7 @@
switch (status) {
case Dumpstate::RunStatus::OK:
return 0;
- break;
+ // TODO(b/111441001): Exit directly in the following cases.
case Dumpstate::RunStatus::HELP:
ShowUsageAndExit(0 /* exit code */);
break;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 35cbdb1..ee952d9 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -142,7 +142,7 @@
float growth_factor_;
int32_t n_runs_;
int32_t average_max_;
- const std::string& path_;
+ std::string path_;
};
/*
@@ -164,6 +164,11 @@
static std::string VERSION_DEFAULT = "default";
/*
+ * Directory used by Dumpstate binary to keep its local files.
+ */
+static const std::string DUMPSTATE_DIRECTORY = "/bugreports";
+
+/*
* Structure that contains the information of an open dump file.
*/
struct DumpData {
@@ -196,7 +201,8 @@
BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE,
BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR,
BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY,
- BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI
+ BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI,
+ BUGREPORT_DEFAULT = android::os::IDumpstate::BUGREPORT_MODE_DEFAULT
};
static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
@@ -300,7 +306,11 @@
*/
bool FinishZipFile();
- /* Gets the path of a bugreport file with the given suffix. */
+ /* Constructs a full path inside directory with file name formatted using the given suffix. */
+ std::string GetPath(const std::string& directory, const std::string& suffix) const;
+
+ /* Constructs a full path inside bugreport_internal_dir_ with file name formatted using the
+ * given suffix. */
std::string GetPath(const std::string& suffix) const;
/* Returns true if the current version supports priority dump feature. */
@@ -314,7 +324,6 @@
/* Sets runtime options. */
void SetOptions(std::unique_ptr<DumpOptions> options);
- // TODO: add other options from DumpState.
/*
* Structure to hold options that determine the behavior of dumpstate.
*/
@@ -333,6 +342,10 @@
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;
+ // Partial path to output file.
std::string use_outfile;
// TODO: rename to MODE.
// Extra options passed as system property.
@@ -381,12 +394,6 @@
// Bugreport format version;
std::string version_ = VERSION_CURRENT;
- // Full path of the directory where the bugreport files will be written.
- std::string bugreport_dir_;
-
- // Full path of the temporary file containing the screenshot (when requested).
- std::string screenshot_path_;
-
time_t now_;
// Base name (without suffix or extensions) of the bugreport files, typically
@@ -397,15 +404,30 @@
// `-d`), but it could be changed by the user..
std::string name_;
- // Full path of the temporary file containing the bugreport.
+ std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY;
+
+ // Full path of the temporary file containing the bugreport, inside bugreport_internal_dir_.
+ // At the very end this file is pulled into the zip file.
std::string tmp_path_;
- // Full path of the file containing the dumpstate logs.
+ // Full path of the file containing the dumpstate logs, inside bugreport_internal_dir_.
+ // This is useful for debugging.
std::string log_path_;
- // Pointer to the actual path, be it zip or text.
+ // Full path of the bugreport file, be it zip or text, inside bugreport_internal_dir_.
std::string path_;
+ // TODO: If temporary this should be removed at the end.
+ // Full path of the temporary file containing the screenshot (when requested).
+ std::string screenshot_path_;
+
+ // TODO(b/111441001): remove when obsolete.
+ // Full path of the final zip file inside the caller-specified directory, if available.
+ std::string final_path_;
+
+ // The caller-specified directory, if available.
+ std::string bugreport_dir_;
+
// Pointer to the zipped file.
std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose};
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 9ca894d..fcf9371 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -36,6 +36,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <cutils/properties.h>
namespace android {
namespace os {
@@ -148,7 +149,10 @@
virtual void SetUp() {
options_ = Dumpstate::DumpOptions();
}
-
+ void TearDown() {
+ // Reset the property
+ property_set("dumpstate.options", "");
+ }
Dumpstate::DumpOptions options_;
};
@@ -163,7 +167,6 @@
EXPECT_EQ(status, Dumpstate::RunStatus::OK);
- // These correspond to bugreport_mode = full, because that's the default.
EXPECT_FALSE(options_.do_add_date);
EXPECT_FALSE(options_.do_zip_file);
EXPECT_EQ("", options_.use_outfile);
@@ -171,10 +174,295 @@
EXPECT_FALSE(options_.use_control_socket);
EXPECT_FALSE(options_.show_header_only);
EXPECT_TRUE(options_.do_vibrate);
- EXPECT_TRUE(options_.do_fb);
+ EXPECT_FALSE(options_.do_fb);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.do_broadcast);
+}
+
+TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("dumpstatez"),
+ const_cast<char*>("-S"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.use_control_socket);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_fb);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.do_broadcast);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("dumpstate"),
+ const_cast<char*>("-s"),
+ };
+ // clang-format on
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.use_socket);
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_EQ("", options_.use_outfile);
+ EXPECT_FALSE(options_.do_add_date);
+ EXPECT_FALSE(options_.do_zip_file);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_fb);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.do_broadcast);
+}
+
+TEST_F(DumpOptionsTest, InitializeFullBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+ property_set("dumpstate.options", "bugreportfull");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_fb);
+ EXPECT_TRUE(options_.do_zip_file);
EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.do_start_service);
+}
+
+TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "bugreportplus");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.do_progress_updates);
+ EXPECT_TRUE(options_.do_start_service);
+ EXPECT_FALSE(options_.do_fb);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "bugreportremote");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.do_vibrate);
+ EXPECT_FALSE(options_.do_fb);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeWearBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "bugreportwear");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_fb);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.do_progress_updates);
+ EXPECT_TRUE(options_.do_start_service);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "bugreporttelephony");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_fb);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.telephony_only);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "bugreportwifi");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_fb);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.wifi_only);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
+ // default: commandline options are not overridden
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("bugreport"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("-B"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-o abc"),
+ };
+ // clang-format on
+
+ property_set("dumpstate.options", "");
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_fb);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+ // Other options retain default values
+ EXPECT_TRUE(options_.do_vibrate);
+ EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.wifi_only);
}
TEST_F(DumpOptionsTest, InitializePartial1) {
@@ -203,10 +491,10 @@
// Other options retain default values
EXPECT_FALSE(options_.show_header_only);
EXPECT_TRUE(options_.do_vibrate);
- EXPECT_TRUE(options_.do_fb);
+ EXPECT_FALSE(options_.do_fb);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
- EXPECT_TRUE(options_.do_broadcast);
+ EXPECT_FALSE(options_.do_broadcast);
}
TEST_F(DumpOptionsTest, InitializePartial2) {
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 6cbb691..d97ffbf 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -229,7 +229,11 @@
}
std::string Dumpstate::GetPath(const std::string& suffix) const {
- return android::base::StringPrintf("%s/%s-%s%s", bugreport_dir_.c_str(), base_name_.c_str(),
+ return GetPath(bugreport_internal_dir_, suffix);
+}
+
+std::string Dumpstate::GetPath(const std::string& directory, const std::string& suffix) const {
+ return android::base::StringPrintf("%s/%s-%s%s", directory.c_str(), base_name_.c_str(),
name_.c_str(), suffix.c_str());
}
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 5412d4d..8fbea8a 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -389,7 +389,7 @@
auto time_left_ms = [end]() {
auto now = std::chrono::steady_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
- return std::max(diff.count(), 0ll);
+ return std::max(diff.count(), 0LL);
};
int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index aad9939..25e5247 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -313,9 +313,14 @@
bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
vold_decrypt == "1";
- const std::string resolve_startup_string_arg =
+ const std::string resolve_startup_string_arg =
MapPropertyToArg("dalvik.vm.dex2oat-resolve-startup-strings",
"--resolve-startup-const-strings=%s");
+
+ const std::string image_block_size_arg =
+ MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size",
+ "--max-image-block-size=%s");
+
const bool generate_debug_info = GetBoolProperty("debug.generate-debug-info", false);
std::string image_format_arg;
@@ -430,6 +435,7 @@
AddRuntimeArg(dex2oat_Xmx_arg);
AddArg(resolve_startup_string_arg);
+ AddArg(image_block_size_arg);
AddArg(dex2oat_compiler_filter_arg);
AddArg(dex2oat_threads_arg);
AddArg(dex2oat_swap_fd);
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index a6d7a78..c706d91 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -376,23 +376,23 @@
}
mServicesTable.setDescription(
- "All binderized services (registered services through hwservicemanager)");
+ "| All binderized services (registered with hwservicemanager)");
mPassthroughRefTable.setDescription(
- "All interfaces that getService() has ever return as a passthrough interface;\n"
- "PIDs / processes shown below might be inaccurate because the process\n"
- "might have relinquished the interface or might have died.\n"
- "The Server / Server CMD column can be ignored.\n"
- "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
- "the library and successfully fetched the passthrough implementation.");
+ "| All interfaces that getService() has ever returned as a passthrough interface;\n"
+ "| PIDs / processes shown below might be inaccurate because the process\n"
+ "| might have relinquished the interface or might have died.\n"
+ "| The Server / Server CMD column can be ignored.\n"
+ "| The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
+ "| the library and successfully fetched the passthrough implementation.");
mImplementationsTable.setDescription(
- "All available passthrough implementations (all -impl.so files).\n"
- "These may return subclasses through their respective HIDL_FETCH_I* functions.");
+ "| All available passthrough implementations (all -impl.so files).\n"
+ "| These may return subclasses through their respective HIDL_FETCH_I* functions.");
mManifestHalsTable.setDescription(
- "All HALs that are in VINTF manifest.");
+ "| All HALs that are in VINTF manifest.");
mLazyHalsTable.setDescription(
- "All HALs that are declared in VINTF manifest:\n"
- " - as hwbinder HALs but are not registered to hwservicemanager, and\n"
- " - as hwbinder/passthrough HALs with no implementation.");
+ "| All HALs that are declared in VINTF manifest:\n"
+ "| - as hwbinder HALs but are not registered to hwservicemanager, and\n"
+ "| - as hwbinder/passthrough HALs with no implementation.");
}
bool ListCommand::addEntryWithInstance(const TableEntry& entry,
@@ -972,10 +972,10 @@
thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
return OK;
}, "print VINTF info. This column contains a comma-separated list of:\n"
- " - DM: device manifest\n"
- " - DC: device compatibility matrix\n"
- " - FM: framework manifest\n"
- " - FC: framework compatibility matrix"});
+ " - DM: if the HAL is in the device manifest\n"
+ " - DC: if the HAL is in the device compatibility matrix\n"
+ " - FM: if the HAL is in the framework manifest\n"
+ " - FC: if the HAL is in the framework compatibility matrix"});
mOptions.push_back({'S', "service-status", no_argument, v++, [](ListCommand* thiz, const char*) {
thiz->mSelectedColumns.push_back(TableColumnType::SERVICE_STATUS);
return OK;
@@ -1054,7 +1054,7 @@
return OK;
}, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
"section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
- "passthrough_libs), and (v|vintf).\nDefault is `bcl`."});
+ "passthrough_libs), (v|vintf), and (z|lazy).\nDefault is `bcl`."});
}
// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
@@ -1150,7 +1150,7 @@
}
if (mSelectedColumns.empty()) {
- mSelectedColumns = {TableColumnType::RELEASED,
+ mSelectedColumns = {TableColumnType::VINTF, TableColumnType::RELEASED,
TableColumnType::INTERFACE_NAME, TableColumnType::THREADS,
TableColumnType::SERVER_PID, TableColumnType::CLIENT_PIDS};
}
@@ -1210,7 +1210,7 @@
err() << "list:" << std::endl
<< " lshal" << std::endl
<< " lshal list" << std::endl
- << " List all hals with default ordering and columns (`lshal list -liepc`)" << std::endl
+ << " List all hals with default ordering and columns (`lshal list -Vliepc`)" << std::endl
<< " lshal list [-h|--help]" << std::endl
<< " -h, --help: Print help message for list (`lshal help list`)" << std::endl
<< " lshal [list] [OPTIONS...]" << std::endl;
diff --git a/cmds/rss_hwm_reset/Android.bp b/cmds/rss_hwm_reset/Android.bp
new file mode 100644
index 0000000..15f10ef
--- /dev/null
+++ b/cmds/rss_hwm_reset/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+ name: "rss_hwm_reset",
+
+ srcs: [
+ "rss_hwm_reset.cc",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+
+ init_rc: ["rss_hwm_reset.rc"],
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.cc b/cmds/rss_hwm_reset/rss_hwm_reset.cc
new file mode 100644
index 0000000..1626e7e
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+ * rss_hwm_reset clears the RSS high-water mark counters for all currently
+ * running processes. It writes "5" to /proc/PID/clear_refs for every PID.
+ *
+ * It runs in its own process becuase dac_override capability is required
+ * in order to write to other processes' clear_refs.
+ *
+ * It is invoked from a system service by flipping sys.rss_hwm_reset.on
+ * property to "1".
+ */
+
+#define LOG_TAG "rss_hwm_reset"
+
+#include <dirent.h>
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+
+namespace {
+// Resets RSS HWM counter for the selected process by writing 5 to
+// /proc/PID/clear_refs.
+void reset_rss_hwm(const char* pid) {
+ std::string clear_refs_path =
+ ::android::base::StringPrintf("/proc/%s/clear_refs", pid);
+ ::android::base::WriteStringToFile("5", clear_refs_path);
+}
+}
+
+// Clears RSS HWM counters for all currently running processes.
+int main(int /* argc */, char** /* argv[] */) {
+ DIR* dirp = opendir("/proc");
+ if (dirp == nullptr) {
+ ALOGE("unable to read /proc");
+ return 1;
+ }
+ struct dirent* entry;
+ while ((entry = readdir(dirp)) != nullptr) {
+ // Skip entries that are not directories.
+ if (entry->d_type != DT_DIR) continue;
+ // Skip entries that do not contain only numbers.
+ const char* pid = entry->d_name;
+ while (*pid) {
+ if (*pid < '0' || *pid > '9') break;
+ pid++;
+ }
+ if (*pid != 0) continue;
+
+ pid = entry->d_name;
+ reset_rss_hwm(pid);
+ }
+ closedir(dirp);
+ return 0;
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.rc b/cmds/rss_hwm_reset/rss_hwm_reset.rc
new file mode 100644
index 0000000..fbbc820
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.rc
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+service rss_hwm_reset /system/bin/rss_hwm_reset
+ class late_start
+ disabled
+ oneshot
+ user nobody
+ group nobody readproc
+ writepid /dev/cpuset/system-background/tasks
+ capabilities DAC_OVERRIDE
+
+on property:sys.rss_hwm_reset.on=1
+ start rss_hwm_reset
+ setprop sys.rss_hwm_reset.on 0
diff --git a/headers/media_plugin/media/cas/DescramblerAPI.h b/headers/media_plugin/media/cas/DescramblerAPI.h
index 033c8ce..c57f606 100644
--- a/headers/media_plugin/media/cas/DescramblerAPI.h
+++ b/headers/media_plugin/media/cas/DescramblerAPI.h
@@ -72,12 +72,12 @@
// associated MediaCas session is used to load decryption keys
// into the crypto/cas plugin. The keys are then referenced by key-id
// in the 'key' parameter to the decrypt() method.
- // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if
+ // Should return NO_ERROR on success, ERROR_CAS_SESSION_NOT_OPENED if
// the session is not opened and a code from MediaErrors.h otherwise.
virtual status_t setMediaCasSession(const CasSessionId& sessionId) = 0;
// If the error returned falls into the range
- // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be
+ // ERROR_CAS_VENDOR_MIN..ERROR_CAS_VENDOR_MAX, errorDetailMsg should be
// filled in with an appropriate string.
// At the java level these special errors will then trigger a
// MediaCodec.CryptoException that gives clients access to both
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 4d24680..ed9531e 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -110,6 +110,47 @@
#endif /* __ANDROID_API__ >= 23 */
+#if __ANDROID_API__ >= 29
+
+/**
+ * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated
+ * with Domain Name |dname| on the given |network|.
+ * The typical value for |ns_class| is ns_c_in, while |type| can be any
+ * record type (for instance, ns_t_aaaa or ns_t_txt).
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nquery(net_handle_t network,
+ const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29);
+
+/**
+ * Issue the query |msg| on the given |network|.
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nsend(net_handle_t network,
+ const unsigned char *msg, int msglen) __INTRODUCED_IN(29);
+
+/**
+ * Read a result for the query associated with the |fd| descriptor.
+ *
+ * Returns:
+ * < 0: negative POSIX error code (see errno.h for possible values). |rcode| is not set.
+ * >= 0: length of |answer|. |rcode| is the resolver return code (e.g., ns_r_nxdomain)
+ */
+int android_res_nresult(int fd,
+ int *rcode, unsigned char *answer, int anslen) __INTRODUCED_IN(29);
+
+/**
+ * Attempts to cancel the in-progress query associated with the |nsend_fd|
+ * descriptor.
+ */
+void android_res_cancel(int nsend_fd) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
__END_DECLS
#endif // ANDROID_MULTINETWORK_H
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 07d5c4b..b2db945 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -467,7 +467,6 @@
status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
{
- const sp<ProcessState> proc(ProcessState::self());
status_t err;
const uint8_t *data = parcel->mData;
const binder_size_t *objects = parcel->mObjects;
@@ -520,6 +519,7 @@
err = NO_ERROR;
if (numObjects > 0) {
+ const sp<ProcessState> proc(ProcessState::self());
// grow objects
if (mObjectsCapacity < mObjectsSize + numObjects) {
size_t newSize = ((mObjectsSize + numObjects)*3)/2;
@@ -2543,8 +2543,11 @@
void Parcel::releaseObjects()
{
- const sp<ProcessState> proc(ProcessState::self());
size_t i = mObjectsSize;
+ if (i == 0) {
+ return;
+ }
+ sp<ProcessState> proc(ProcessState::self());
uint8_t* const data = mData;
binder_size_t* const objects = mObjects;
while (i > 0) {
@@ -2557,8 +2560,11 @@
void Parcel::acquireObjects()
{
- const sp<ProcessState> proc(ProcessState::self());
size_t i = mObjectsSize;
+ if (i == 0) {
+ return;
+ }
+ const sp<ProcessState> proc(ProcessState::self());
uint8_t* const data = mData;
binder_size_t* const objects = mObjects;
while (i > 0) {
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 14ce4cb..1b69dfd 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -23,6 +23,8 @@
"include_apex",
],
+ cflags: ["-Wall", "-Wextra", "-Werror"],
+
srcs: [
"ibinder.cpp",
"ibinder_jni.cpp",
@@ -39,9 +41,11 @@
"libutils",
],
- cpp_std: "c++17",
-
version_script: "libbinder_ndk.map.txt",
+ stubs: {
+ symbol_file: "libbinder_ndk.map.txt",
+ versions: ["29"],
+ },
}
ndk_headers {
@@ -52,10 +56,12 @@
"include_ndk/android/*.h",
],
license: "NOTICE",
+ draft: true,
}
ndk_library {
name: "libbinder_ndk",
symbol_file: "libbinder_ndk.map.txt",
first_version: "29",
+ draft: true,
}
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index c6fcaa4..ff1860e 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -163,9 +163,7 @@
ScopedAResource& operator=(ScopedAResource&&) = delete;
// move-constructing is okay
- ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) {
- other.mT = DEFAULT;
- }
+ ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) { other.mT = DEFAULT; }
private:
T mT;
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 3594349..2258210 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -54,6 +54,31 @@
void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29);
/**
+ * Sets the position within the parcel.
+ *
+ * \param parcel The parcel of which to set the position.
+ * \param position Position of the parcel to set. This must be a value returned by
+ * AParcel_getDataPosition. Positions are constant for a given parcel between processes.
+ *
+ * \return STATUS_OK on success. If position is negative, then STATUS_BAD_VALUE will be returned.
+ */
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position)
+ __INTRODUCED_IN(29);
+
+/**
+ * Gets the current position within the parcel.
+ *
+ * \param parcel The parcel of which to get the position.
+ *
+ * \return The size of the parcel. This will always be greater than 0. The values returned by this
+ * function before and after calling various reads and writes are not defined. Only the delta
+ * between two positions between a specific sequence of calls is defined. For instance, if position
+ * is X, writeBool is called, and then position is Y, readBool can be called from position X will
+ * return the same value, and then position will be Y.
+ */
+int32_t AParcel_getDataPosition(const AParcel* parcel) __INTRODUCED_IN(29);
+
+/**
* This is called to allocate a buffer for a C-style string (null-terminated). The returned buffer
* should be at least length bytes. This includes space for a null terminator. For a string, length
* will always be strictly less than or equal to the maximum size that can be held in a size_t and
@@ -124,7 +149,49 @@
* not required to be null-terminated. If the object at index is null, then this should be null.
*/
typedef const char* (*AParcel_stringArrayElementGetter)(const void* arrayData, size_t index,
- size_t* outLength);
+ int32_t* outLength);
+
+/**
+ * This is called to allocate an array of size 'length'. If length is -1, then a 'null' array (or
+ * equivalent) should be created.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param arrayData some external representation of an array
+ * \param length the length to allocate this array to
+ *
+ * \return true if allocation succeeded. If length is -1, a true return here means that a 'null'
+ * value (or equivalent) was successfully stored.
+ */
+typedef bool (*AParcel_parcelableArrayAllocator)(void* arrayData, int32_t length);
+
+/**
+ * This is called to parcel the underlying data from an arrayData object at index.
+ *
+ * See also AParcel_writeParcelableArray
+ *
+ * \param parcel parcel to write the parcelable to
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be retrieved.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_writeParcelableElement)(AParcel* parcel, const void* arrayData,
+ size_t index);
+
+/**
+ * This is called to set an underlying value in an arrayData object at index.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param parcel parcel to read the parcelable from
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be set.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_readParcelableElement)(const AParcel* parcel, void* arrayData,
+ size_t index);
// @START-PRIMITIVE-VECTOR-GETTERS
/**
@@ -472,6 +539,40 @@
AParcel_stringArrayElementAllocator elementAllocator)
__INTRODUCED_IN(29);
+/**
+ * Writes an array of parcelables (user-defined types) to the next location in a non-null parcel.
+ *
+ * \param parcel the parcel to write to.
+ * \param arrayData an array of size 'length' (or null if length is -1, may be null if length is 0).
+ * \param length the length of arrayData or -1 if this represents a null array.
+ * \param elementWriter function to be called for every array index to write the user-defined type
+ * at that location.
+ *
+ * \return STATUS_OK on successful write.
+ */
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+ AParcel_writeParcelableElement elementWriter)
+ __INTRODUCED_IN(29);
+
+/**
+ * Reads an array of parcelables (user-defined types) from the next location in a non-null parcel.
+ *
+ * First, allocator will be called with the length of the array. If the allocation succeeds and the
+ * length is greater than zero, elementReader will be called for every index to read the
+ * corresponding parcelable.
+ *
+ * \param parcel the parcel to read from.
+ * \param arrayData some external representation of an array.
+ * \param allocator the callback that will be called to allocate the array.
+ * \param elementReader the callback that will be called to fill out individual elements.
+ *
+ * \return STATUS_OK on successful read.
+ */
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+ AParcel_parcelableArrayAllocator allocator,
+ AParcel_readParcelableElement elementReader)
+ __INTRODUCED_IN(29);
+
// @START-PRIMITIVE-READ-WRITE
/**
* Writes int32_t value to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index f99c3a9..f3bc31b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -43,7 +43,7 @@
if (length < 0) return false;
std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
- if (length > vec->max_size()) return false;
+ if (static_cast<size_t>(length) > vec->max_size()) return false;
vec->resize(length);
*outBuffer = vec->data();
@@ -65,7 +65,7 @@
*vec = std::optional<std::vector<T>>(std::vector<T>{});
- if (length > (*vec)->max_size()) return false;
+ if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
(*vec)->resize(length);
*outBuffer = (*vec)->data();
@@ -88,7 +88,7 @@
if (length < 0) return false;
std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
- if (length > vec->max_size()) return false;
+ if (static_cast<size_t>(length) > vec->max_size()) return false;
vec->resize(length);
return true;
@@ -116,7 +116,7 @@
*vec = std::optional<std::vector<T>>(std::vector<T>{});
- if (length > (*vec)->max_size()) return false;
+ if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
(*vec)->resize(length);
return true;
@@ -299,7 +299,7 @@
* index.
*/
static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index,
- size_t* outLength) {
+ int32_t* outLength) {
const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData);
const std::string& element = vec->at(index);
@@ -327,7 +327,7 @@
*/
static inline const char* AParcel_nullableStdVectorStringElementGetter(const void* vectorData,
size_t index,
- size_t* outLength) {
+ int32_t* outLength) {
const std::optional<std::vector<std::optional<std::string>>>* vec =
static_cast<const std::optional<std::vector<std::optional<std::string>>>*>(vectorData);
const std::optional<std::string>& element = vec->value().at(index);
@@ -420,6 +420,46 @@
AParcel_nullableStdVectorStringElementAllocator);
}
+/**
+ * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_writeStdVectorParcelableElement(AParcel* parcel, const void* vectorData,
+ size_t index) {
+ const std::vector<P>* vector = static_cast<const std::vector<P>*>(vectorData);
+ return vector->at(index).writeToParcel(parcel);
+}
+
+/**
+ * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_readStdVectorParcelableElement(const AParcel* parcel, void* vectorData,
+ size_t index) {
+ std::vector<P>* vector = static_cast<std::vector<P>*>(vectorData);
+ return vector->at(index).readFromParcel(parcel);
+}
+
+/**
+ * Convenience API for writing a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<P>& vec) {
+ const void* vectorData = static_cast<const void*>(&vec);
+ return AParcel_writeParcelableArray(parcel, vectorData, vec.size(),
+ AParcel_writeStdVectorParcelableElement<P>);
+}
+
+/**
+ * Convenience API for reading a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<P>* vec) {
+ void* vectorData = static_cast<void*>(vec);
+ return AParcel_readParcelableArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<P>,
+ AParcel_readStdVectorParcelableElement<P>);
+}
+
// @START
/**
* Writes a vector of int32_t to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 41df90b..ee7132f 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -25,6 +25,7 @@
AIBinder_Weak_new;
AIBinder_Weak_promote;
AParcel_delete;
+ AParcel_getDataPosition;
AParcel_readBool;
AParcel_readBoolArray;
AParcel_readByte;
@@ -39,6 +40,7 @@
AParcel_readInt32Array;
AParcel_readInt64;
AParcel_readInt64Array;
+ AParcel_readParcelableArray;
AParcel_readParcelFileDescriptor;
AParcel_readStatusHeader;
AParcel_readString;
@@ -48,6 +50,7 @@
AParcel_readUint32Array;
AParcel_readUint64;
AParcel_readUint64Array;
+ AParcel_setDataPosition;
AParcel_writeBool;
AParcel_writeBoolArray;
AParcel_writeByte;
@@ -62,6 +65,7 @@
AParcel_writeInt32Array;
AParcel_writeInt64;
AParcel_writeInt64Array;
+ AParcel_writeParcelableArray;
AParcel_writeParcelFileDescriptor;
AParcel_writeStatusHeader;
AParcel_writeString;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 3c32100..ae2276e 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -173,7 +173,7 @@
Parcel* rawParcel = parcel->get();
- for (size_t i = 0; i < length; i++) {
+ for (int32_t i = 0; i < length; i++) {
status = (rawParcel->*write)(getter(arrayData, i));
if (status != STATUS_OK) return PruneStatusT(status);
@@ -197,7 +197,7 @@
if (length <= 0) return STATUS_OK;
- for (size_t i = 0; i < length; i++) {
+ for (int32_t i = 0; i < length; i++) {
T readTarget;
status = (rawParcel->*read)(&readTarget);
if (status != STATUS_OK) return PruneStatusT(status);
@@ -212,6 +212,19 @@
delete parcel;
}
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
+ if (position < 0) {
+ return STATUS_BAD_VALUE;
+ }
+
+ parcel->get()->setDataPosition(position);
+ return STATUS_OK;
+}
+
+int32_t AParcel_getDataPosition(const AParcel* parcel) {
+ return parcel->get()->dataPosition();
+}
+
binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
return parcel->get()->writeStrongBinder(writeBinder);
@@ -363,12 +376,12 @@
if (status != STATUS_OK) return status;
if (length <= 0) return STATUS_OK;
- for (size_t i = 0; i < length; i++) {
- size_t length = 0;
- const char* str = getter(arrayData, i, &length);
- if (str == nullptr && length != -1) return STATUS_BAD_VALUE;
+ for (int32_t i = 0; i < length; i++) {
+ int32_t elementLength = 0;
+ const char* str = getter(arrayData, i, &elementLength);
+ if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
- binder_status_t status = AParcel_writeString(parcel, str, length);
+ binder_status_t status = AParcel_writeString(parcel, str, elementLength);
if (status != STATUS_OK) return status;
}
@@ -379,7 +392,7 @@
// allocator.
struct StringArrayElementAllocationAdapter {
void* arrayData; // stringData from the NDK
- size_t index; // index into the string array
+ int32_t index; // index into the string array
AParcel_stringArrayElementAllocator elementAllocator;
static bool Allocator(void* stringData, int32_t length, char** buffer) {
@@ -420,6 +433,45 @@
return STATUS_OK;
}
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+ AParcel_writeParcelableElement elementWriter) {
+ // we have no clue if arrayData represents a null object or not, we can only infer from length
+ bool arrayIsNull = length < 0;
+ binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
+ if (status != STATUS_OK) return status;
+ if (length <= 0) return STATUS_OK;
+
+ for (int32_t i = 0; i < length; i++) {
+ binder_status_t status = elementWriter(parcel, arrayData, i);
+ if (status != STATUS_OK) return status;
+ }
+
+ return STATUS_OK;
+}
+
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+ AParcel_parcelableArrayAllocator allocator,
+ AParcel_readParcelableElement elementReader) {
+ const Parcel* rawParcel = parcel->get();
+
+ int32_t length;
+ status_t status = rawParcel->readInt32(&length);
+
+ if (status != STATUS_OK) return PruneStatusT(status);
+ if (length < -1) return STATUS_BAD_VALUE;
+
+ if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
+
+ if (length == -1) return STATUS_OK; // null array
+
+ for (int32_t i = 0; i < length; i++) {
+ binder_status_t status = elementReader(parcel, arrayData, i);
+ if (status != STATUS_OK) return status;
+ }
+
+ return STATUS_OK;
+}
+
// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
// libbinder and this library.
// @START
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index 67481cf..b29b6e7 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -22,7 +22,6 @@
strip: {
none: true,
},
- cpp_std: "c++17",
cflags: [
"-O0",
"-g",
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 73c2eba..2dd86ba 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1295,7 +1295,7 @@
}
IPCThreadState::self()->flushCommands(); // flush BC_ENTER_LOOPER
- epoll_fd = epoll_create1(0);
+ epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
return 1;
}
diff --git a/libs/binder/tests/binderValueTypeTest.cpp b/libs/binder/tests/binderValueTypeTest.cpp
index 15949d4..f8922b0 100644
--- a/libs/binder/tests/binderValueTypeTest.cpp
+++ b/libs/binder/tests/binderValueTypeTest.cpp
@@ -75,13 +75,13 @@
VALUE_TYPE_TEST(bool, Boolean, true)
VALUE_TYPE_TEST(int32_t, Int, 31337)
-VALUE_TYPE_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_TEST(int64_t, Long, 13370133701337L)
VALUE_TYPE_TEST(double, Double, 3.14159265358979323846)
VALUE_TYPE_TEST(String16, String, String16("Lovely"))
VALUE_TYPE_VECTOR_TEST(bool, Boolean, true)
VALUE_TYPE_VECTOR_TEST(int32_t, Int, 31337)
-VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337L)
VALUE_TYPE_VECTOR_TEST(double, Double, 3.14159265358979323846)
VALUE_TYPE_VECTOR_TEST(String16, String, String16("Lovely"))
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 8b2f842..35296a9 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -47,6 +47,7 @@
"android.hardware.camera.provider@2.4::ICameraProvider",
"android.hardware.drm@1.0::IDrmFactory",
"android.hardware.graphics.composer@2.1::IComposer",
+ "android.hardware.health@2.0::IHealth",
"android.hardware.media.omx@1.0::IOmx",
"android.hardware.media.omx@1.0::IOmxStore",
"android.hardware.sensors@1.0::ISensors",
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index e22bc70..d2d27e8 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -332,6 +332,34 @@
return result;
}
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_VIEWPORT, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to transact: %d", result);
+ return result;
+ }
+ result = reply.readInt32();
+ if (result == NO_ERROR) {
+ result = reply.read(*outViewport);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to read: %d", result);
+ return result;
+ }
+ }
+ return result;
+ }
+
virtual int getActiveConfig(const sp<IBinder>& display)
{
Parcel data, reply;
@@ -724,6 +752,26 @@
}
return NO_ERROR;
}
+ case GET_DISPLAY_VIEWPORT: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ Rect outViewport;
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to readStrongBinder: %d", result);
+ return result;
+ }
+ result = getDisplayViewport(display, &outViewport);
+ result = reply->writeInt32(result);
+ if (result == NO_ERROR) {
+ result = reply->write(outViewport);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to write: %d", result);
+ return result;
+ }
+ }
+ return NO_ERROR;
+ }
case GET_ACTIVE_CONFIG: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 63560c4..f3c6fd2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -718,6 +718,10 @@
return NO_ERROR;
}
+status_t SurfaceComposerClient::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ return ComposerService::getComposerService()->getDisplayViewport(display, outViewport);
+}
+
int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) {
return ComposerService::getComposerService()->getActiveConfig(display);
}
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index 3b89291..b1e44bb 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -896,7 +896,7 @@
int const* constFds = static_cast<int const*>(baseFds.get());
numFds = baseNumFds;
if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
- for (auto nhA : nhAA) {
+ for (const auto& nhA : nhAA) {
for (auto nh : nhA) {
if (nh != nullptr) {
native_handle_close(nh);
@@ -907,8 +907,8 @@
return false;
}
- for (auto nhA : nhAA) {
- for (auto nh : nhA) {
+ for (const auto& nhA : nhAA) {
+ for (const auto& nh : nhA) {
if (nh != nullptr) {
native_handle_delete(nh);
}
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e401572..99a3a75 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -157,6 +157,9 @@
virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats) = 0;
+ /* returns display viewport information of the given display */
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) = 0;
+
/* indicates which of the configurations returned by getDisplayInfo is
* currently active */
virtual int getActiveConfig(const sp<IBinder>& display) = 0;
@@ -250,7 +253,8 @@
ENABLE_VSYNC_INJECTIONS,
INJECT_VSYNC,
GET_LAYER_DEBUG_INFO,
- CREATE_SCOPED_CONNECTION
+ CREATE_SCOPED_CONNECTION,
+ GET_DISPLAY_VIEWPORT
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 377fe68..ad8a8b0 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -79,6 +79,9 @@
static status_t getDisplayInfo(const sp<IBinder>& display,
DisplayInfo* info);
+ // Get the display viewport for the given display
+ static status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
+
// Get the index of the current active configuration (relative to the list
// returned by getDisplayInfo)
static int getActiveConfig(const sp<IBinder>& display);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 2c02ba6..6e196bf 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -581,6 +581,9 @@
Vector<DisplayInfo>* /*configs*/) override { return NO_ERROR; }
status_t getDisplayStats(const sp<IBinder>& /*display*/,
DisplayStatInfo* /*stats*/) override { return NO_ERROR; }
+ status_t getDisplayViewport(const sp<IBinder>& /*display*/, Rect* /*outViewport*/) override {
+ return NO_ERROR;
+ }
int getActiveConfig(const sp<IBinder>& /*display*/) override { return 0; }
status_t setActiveConfig(const sp<IBinder>& /*display*/, int /*id*/)
override {
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index a2d6a8a..2f39976 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -16,7 +16,6 @@
cc_library {
name: "libinput",
- cpp_std: "c++17",
host_supported: true,
cflags: [
"-Wall",
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 5fbb3b2..d74bdb3 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -43,10 +43,6 @@
"-Wno-unused-function",
],
- cppflags: [
- "-std=c++1z"
- ],
-
version_script: "libnativewindow.map.txt",
srcs: [
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 9ca4941..52b4582 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -15,12 +15,31 @@
*/
/**
- * @addtogroup NativeActivity Native Activity
- * @{
- */
-
-/**
* @file hardware_buffer.h
+ * @brief API for native hardware buffers.
+ */
+/**
+ * @defgroup AHardwareBuffer Native Hardware Buffer
+ *
+ * AHardwareBuffer objects represent chunks of memory that can be
+ * accessed by various hardware components in the system. It can be
+ * easily converted to the Java counterpart
+ * android.hardware.HardwareBuffer and passed between processes using
+ * Binder. All operations involving AHardwareBuffer and HardwareBuffer
+ * are zero-copy, i.e., passing AHardwareBuffer to another process
+ * creates a shared view of the same region of memory.
+ *
+ * AHardwareBuffers can be bound to EGL/OpenGL and Vulkan primitives.
+ * For EGL, use the extension function eglGetNativeClientBufferANDROID
+ * to obtain an EGLClientBuffer and pass it directly to
+ * eglCreateImageKHR. Refer to the EGL extensions
+ * EGL_ANDROID_get_native_client_buffer and
+ * EGL_ANDROID_image_native_buffer for more information. In Vulkan,
+ * the contents of the AHardwareBuffer can be accessed as external
+ * memory. See the VK_ANDROID_external_memory_android_hardware_buffer
+ * extension for details.
+ *
+ * @{
*/
#ifndef ANDROID_HARDWARE_BUFFER_H
@@ -37,7 +56,7 @@
/**
* Buffer pixel formats.
*/
-enum {
+enum AHardwareBuffer_Format {
/**
* Corresponding formats:
* Vulkan: VK_FORMAT_R8G8B8A8_UNORM
@@ -83,8 +102,10 @@
AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,
/**
- * An opaque binary blob format that must have height 1, with width equal to
- * the buffer size in bytes.
+ * Opaque binary blob format.
+ * Must have height 1 and one layer, with width equal to the buffer
+ * size in bytes. Corresponds to Vulkan buffers and OpenGL buffer
+ * objects. Can be bound to the latter using GL_EXT_external_buffer.
*/
AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
@@ -134,21 +155,39 @@
/**
* Buffer usage flags, specifying how the buffer will be accessed.
*/
-enum {
- /// The buffer will never be read by the CPU.
+enum AHardwareBuffer_UsageFlags {
+ /// The buffer will never be locked for direct CPU reads using the
+ /// AHardwareBuffer_lock() function. Note that reading the buffer
+ /// using OpenGL or Vulkan functions or memory mappings is still
+ /// allowed.
AHARDWAREBUFFER_USAGE_CPU_READ_NEVER = 0UL,
- /// The buffer will sometimes be read by the CPU.
+ /// The buffer will sometimes be locked for direct CPU reads using
+ /// the AHardwareBuffer_lock() function. Note that reading the
+ /// buffer using OpenGL or Vulkan functions or memory mappings
+ /// does not require the presence of this flag.
AHARDWAREBUFFER_USAGE_CPU_READ_RARELY = 2UL,
- /// The buffer will often be read by the CPU.
+ /// The buffer will often be locked for direct CPU reads using
+ /// the AHardwareBuffer_lock() function. Note that reading the
+ /// buffer using OpenGL or Vulkan functions or memory mappings
+ /// does not require the presence of this flag.
AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN = 3UL,
/// CPU read value mask.
AHARDWAREBUFFER_USAGE_CPU_READ_MASK = 0xFUL,
- /// The buffer will never be written by the CPU.
+ /// The buffer will never be locked for direct CPU writes using the
+ /// AHardwareBuffer_lock() function. Note that writing the buffer
+ /// using OpenGL or Vulkan functions or memory mappings is still
+ /// allowed.
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER = 0UL << 4,
- /// The buffer will sometimes be written to by the CPU.
+ /// The buffer will sometimes be locked for direct CPU writes using
+ /// the AHardwareBuffer_lock() function. Note that writing the
+ /// buffer using OpenGL or Vulkan functions or memory mappings
+ /// does not require the presence of this flag.
AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY = 2UL << 4,
- /// The buffer will often be written to by the CPU.
+ /// The buffer will often be locked for direct CPU writes using
+ /// the AHardwareBuffer_lock() function. Note that writing the
+ /// buffer using OpenGL or Vulkan functions or memory mappings
+ /// does not require the presence of this flag.
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN = 3UL << 4,
/// CPU write value mask.
AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK = 0xFUL << 4,
@@ -156,24 +195,51 @@
/// The buffer will be read from by the GPU as a texture.
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE = 1UL << 8,
/**
- * The buffer will be written to by the GPU as a framebuffer attachment.
- * Note that the name of this flag is somewhat misleading: it does not imply
- * that the buffer contains a color format. A buffer with depth or stencil
- * format that will be used as a framebuffer attachment should also have
- * this flag.
+ * The buffer will be written to by the GPU as a framebuffer
+ * attachment.
+ *
+ * Note that the name of this flag is somewhat misleading: it does
+ * not imply that the buffer contains a color format. A buffer with
+ * depth or stencil format that will be used as a framebuffer
+ * attachment should also have this flag.
*/
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT = 1UL << 9,
- /// The buffer must not be used outside of a protected hardware path.
+ /**
+ * The buffer is protected from direct CPU access or being read by
+ * non-secure hardware, such as video encoders.
+ *
+ * This flag is incompatible with CPU read and write flags. It is
+ * mainly used when handling DRM video. Refer to the EGL extension
+ * EGL_EXT_protected_content and GL extension
+ * GL_EXT_protected_textures for more information on how these
+ * buffers are expected to behave.
+ */
AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT = 1UL << 14,
/// The buffer will be read by a hardware video encoder.
AHARDWAREBUFFER_USAGE_VIDEO_ENCODE = 1UL << 16,
- /// The buffer will be used for direct writes from sensors.
+ /**
+ * The buffer will be used for direct writes from sensors.
+ * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
+ */
AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA = 1UL << 23,
- /// The buffer will be used as a shader storage or uniform buffer object.
+ /**
+ * The buffer will be used as a shader storage or uniform buffer object.
+ * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
+ */
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER = 1UL << 24,
- /// The buffer will be used as a cube map texture.
+ /**
+ * The buffer will be used as a cube map texture.
+ * When this flag is present, the buffer must have a layer count
+ * that is a multiple of 6. Note that buffers with this flag must be
+ * bound to OpenGL textures using the extension
+ * GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
+ */
AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP = 1UL << 25,
- /// The buffer contains a complete mipmap hierarchy.
+ /**
+ * The buffer contains a complete mipmap hierarchy.
+ * Note that buffers with this flag must be bound to OpenGL textures using
+ * the extension GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
+ */
AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE = 1UL << 26,
AHARDWAREBUFFER_USAGE_VENDOR_0 = 1ULL << 28,
@@ -199,27 +265,42 @@
};
/**
- * Buffer description. Used for allocating new buffers and querying parameters
- * of existing ones.
+ * Buffer description. Used for allocating new buffers and querying
+ * parameters of existing ones.
*/
typedef struct AHardwareBuffer_Desc {
uint32_t width; ///< Width in pixels.
uint32_t height; ///< Height in pixels.
- uint32_t layers; ///< Number of images in an image array.
- uint32_t format; ///< One of AHARDWAREBUFFER_FORMAT_*
- uint64_t usage; ///< Combination of AHARDWAREBUFFER_USAGE_*
+ /**
+ * Number of images in an image array. AHardwareBuffers with one
+ * layer correspond to regular 2D textures. AHardwareBuffers with
+ * more than layer correspond to texture arrays. If the layer count
+ * is a multiple of 6 and the usage flag
+ * AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP is present, the buffer is
+ * a cube map or a cube map array.
+ */
+ uint32_t layers;
+ uint32_t format; ///< One of AHardwareBuffer_Format.
+ uint64_t usage; ///< Combination of AHardwareBuffer_UsageFlags.
uint32_t stride; ///< Row stride in pixels, ignored for AHardwareBuffer_allocate()
uint32_t rfu0; ///< Initialize to zero, reserved for future use.
uint64_t rfu1; ///< Initialize to zero, reserved for future use.
} AHardwareBuffer_Desc;
+/**
+ * Opaque handle for a native hardware buffer.
+ */
typedef struct AHardwareBuffer AHardwareBuffer;
#if __ANDROID_API__ >= 26
/**
- * Allocates a buffer that backs an AHardwareBuffer using the passed
- * AHardwareBuffer_Desc.
+ * Allocates a buffer that matches the passed AHardwareBuffer_Desc.
+ *
+ * If allocation succeeds, the buffer can be used according to the
+ * usage flags specified in its description. If a buffer is used in ways
+ * not compatible with its usage flags, the results are undefined and
+ * may include program termination.
*
* \return 0 on success, or an error number of the allocation fails for
* any reason. The returned buffer has a reference count of 1.
@@ -227,14 +308,16 @@
int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
/**
- * Acquire a reference on the given AHardwareBuffer object. This prevents the
- * object from being deleted until the last reference is removed.
+ * Acquire a reference on the given AHardwareBuffer object.
+ *
+ * This prevents the object from being deleted until the last reference
+ * is removed.
*/
void AHardwareBuffer_acquire(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
/**
* Remove a reference that was previously acquired with
- * AHardwareBuffer_acquire().
+ * AHardwareBuffer_acquire() or AHardwareBuffer_allocate().
*/
void AHardwareBuffer_release(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
@@ -246,50 +329,73 @@
AHardwareBuffer_Desc* outDesc) __INTRODUCED_IN(26);
/**
- * Lock the AHardwareBuffer for reading or writing, depending on the usage flags
- * passed. This call may block if the hardware needs to finish rendering or if
- * CPU caches need to be synchronized, or possibly for other implementation-
- * specific reasons. If fence is not negative, then it specifies a fence file
- * descriptor that will be signaled when the buffer is locked, otherwise the
- * caller will block until the buffer is available.
+ * Lock the AHardwareBuffer for direct CPU access.
*
- * If \a rect is not NULL, the caller promises to modify only data in the area
- * specified by rect. If rect is NULL, the caller may modify the contents of the
- * entire buffer.
+ * This function can lock the buffer for either reading or writing.
+ * It may block if the hardware needs to finish rendering, if CPU caches
+ * need to be synchronized, or possibly for other implementation-
+ * specific reasons.
*
- * The content of the buffer outside of the specified rect is NOT modified
- * by this call.
+ * The passed AHardwareBuffer must have one layer, otherwise the call
+ * will fail.
*
- * The \a usage parameter may only specify AHARDWAREBUFFER_USAGE_CPU_*. If set,
- * then outVirtualAddress is filled with the address of the buffer in virtual
+ * If \a fence is not negative, it specifies a fence file descriptor on
+ * which to wait before locking the buffer. If it's negative, the caller
+ * is responsible for ensuring that writes to the buffer have completed
+ * before calling this function. Using this parameter is more efficient
+ * than waiting on the fence and then calling this function.
+ *
+ * The \a usage parameter may only specify AHARDWAREBUFFER_USAGE_CPU_*.
+ * If set, then outVirtualAddress is filled with the address of the
+ * buffer in virtual memory. The flags must also be compatible with
+ * usage flags specified at buffer creation: if a read flag is passed,
+ * the buffer must have been created with
+ * AHARDWAREBUFFER_USAGE_CPU_READ_RARELY or
+ * AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN. If a write flag is passed, it
+ * must have been created with AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY or
+ * AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN.
+ *
+ * If \a rect is not NULL, the caller promises to modify only data in
+ * the area specified by rect. If rect is NULL, the caller may modify
+ * the contents of the entire buffer. The content of the buffer outside
+ * of the specified rect is NOT modified by this call.
+ *
+ * It is legal for several different threads to lock a buffer for read
+ * access; none of the threads are blocked.
+ *
+ * Locking a buffer simultaneously for write or read/write is undefined,
+ * but will neither terminate the process nor block the caller.
+ * AHardwareBuffer_lock may return an error or leave the buffer's
+ * content in an indeterminate state.
+ *
+ * If the buffer has AHARDWAREBUFFER_FORMAT_BLOB, it is legal lock it
+ * for reading and writing in multiple threads and/or processes
+ * simultaneously, and the contents of the buffer behave like shared
* memory.
*
- * THREADING CONSIDERATIONS:
- *
- * It is legal for several different threads to lock a buffer for read access;
- * none of the threads are blocked.
- *
- * Locking a buffer simultaneously for write or read/write is undefined, but
- * will neither terminate the process nor block the caller; AHardwareBuffer_lock
- * may return an error or leave the buffer's content into an indeterminate
- * state.
- *
- * \return 0 on success, -EINVAL if \a buffer is NULL or if the usage
- * flags are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or an error
- * number of the lock fails for any reason.
+ * \return 0 on success. -EINVAL if \a buffer is NULL, the usage flags
+ * are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer
+ * has more than one layer. Error number if the lock fails for any other
+ * reason.
*/
int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
/**
- * Unlock the AHardwareBuffer; must be called after all changes to the buffer
- * are completed by the caller. If fence is not NULL then it will be set to a
- * file descriptor that is signaled when all pending work on the buffer is
- * completed. The caller is responsible for closing the fence when it is no
- * longer needed.
+ * Unlock the AHardwareBuffer from direct CPU access.
*
- * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
- * number if the unlock fails for any reason.
+ * Must be called after all changes to the buffer are completed by the
+ * caller. If \a fence is NULL, the function will block until all work
+ * is completed. Otherwise, \a fence will be set either to a valid file
+ * descriptor or to -1. The file descriptor will become signaled once
+ * the unlocking is complete and buffer contents are updated.
+ * The caller is responsible for closing the file descriptor once it's
+ * no longer needed. The value -1 indicates that unlocking has already
+ * completed before the function returned and no further operations are
+ * necessary.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL. Error number if
+ * the unlock fails for any reason.
*/
int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) __INTRODUCED_IN(26);
@@ -302,7 +408,7 @@
int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) __INTRODUCED_IN(26);
/**
- * Receive the AHardwareBuffer from an AF_UNIX socket.
+ * Receive an AHardwareBuffer from an AF_UNIX socket.
*
* \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
* number if the operation fails for any reason.
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 6831f91..6730596 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -15,7 +15,13 @@
*/
/**
- * @addtogroup NativeActivity Native Activity
+ * @defgroup ANativeWindow Native Window
+ *
+ * ANativeWindow represents the producer end of an image queue.
+ * It is the C counterpart of the android.view.Surface object in Java,
+ * and can be converted both ways. Depending on the consumer, images
+ * submitted to ANativeWindow can be shown on the display or sent to
+ * other consumers, such as video encoders.
* @{
*/
@@ -41,7 +47,7 @@
* Legacy window pixel format names, kept for backwards compatibility.
* New code and APIs should use AHARDWAREBUFFER_FORMAT_*.
*/
-enum {
+enum ANativeWindow_LegacyFormat {
// NOTE: these values must match the values from graphics/common/x.x/types.hal
/** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/
@@ -95,7 +101,7 @@
/// memory. This may be >= width.
int32_t stride;
- /// The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
+ /// The format of the buffer. One of AHardwareBuffer_Format.
int32_t format;
/// The actual bits.
@@ -151,7 +157,7 @@
*
* \param width width of the buffers in pixels.
* \param height height of the buffers in pixels.
- * \param format one of AHARDWAREBUFFER_FORMAT_* constants.
+ * \param format one of the AHardwareBuffer_Format constants.
* \return 0 for success, or a negative value on error.
*/
int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS
index d4393d6..81099e8 100644
--- a/libs/sensor/OWNERS
+++ b/libs/sensor/OWNERS
@@ -1,2 +1,3 @@
arthuri@google.com
bduddie@google.com
+bstack@google.com
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index c1f1d25..4aa9f62 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -370,6 +370,10 @@
status_t GraphicBuffer::unflatten(
void const*& buffer, size_t& size, int const*& fds, size_t& count) {
+ if (size < 12 * sizeof(int)) {
+ android_errorWriteLog(0x534e4554, "114223584");
+ return NO_MEMORY;
+ }
int const* buf = static_cast<int const*>(buffer);
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
index 6e303a5..2f14f7c 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
@@ -28,7 +28,7 @@
return -EALREADY;
}
- fd_.reset(epoll_create(64));
+ fd_.reset(epoll_create1(EPOLL_CLOEXEC));
if (fd_.get() < 0)
return -errno;
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
index fa0adf0..f72dabc 100644
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
@@ -66,7 +66,7 @@
prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);
}
-constexpr uint64_t kNanosPerSecond = 1000000000llu;
+constexpr uint64_t kNanosPerSecond = 1000000000LLU;
uint64_t GetClockNs() {
timespec t;
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 4dc669b..233e0fc 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -84,9 +84,6 @@
"-Wno-error=sign-compare", // to fix later
"-Wno-unused-variable",
],
- cppflags: [
- "-std=c++1z"
- ],
shared_libs: sharedLibraries,
whole_static_libs: staticLibraries,
header_libs: headerLibraries,
diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
index 962c745..1cf5f17 100644
--- a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
+++ b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
@@ -11,7 +11,7 @@
namespace dvr {
EpollEventDispatcher::EpollEventDispatcher() {
- epoll_fd_.Reset(epoll_create(64));
+ epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
if (!epoll_fd_) {
ALOGE("Failed to create epoll fd: %s", strerror(errno));
return;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 36deedc..e824238 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -552,15 +552,6 @@
break;
}
}
-
- // If the driver doesn't understand it, we should map sRGB-encoded P3 to
- // sRGB rather than just dropping the colorspace on the floor.
- // For this format, the driver is expected to apply the sRGB
- // transfer function during framebuffer operations.
- if (!copyAttribute && attr[1] == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
- strippedAttribList->push_back(attr[0]);
- strippedAttribList->push_back(EGL_GL_COLORSPACE_SRGB_KHR);
- }
}
if (copyAttribute) {
strippedAttribList->push_back(attr[0]);
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
index 250bbee..47bed65 100644
--- a/services/gpuservice/Android.bp
+++ b/services/gpuservice/Android.bp
@@ -21,7 +21,6 @@
"-Wunused",
"-Wunreachable-code",
],
- cppflags: ["-std=c++1z"],
srcs: [
":gpuservice_sources",
],
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 4d9a2a0..ccc24b9 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -206,7 +206,7 @@
mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
- mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+ mEpollFd = epoll_create1(EPOLL_CLOEXEC);
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
mINotifyFd = inotify_init();
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index b37b7fd..efa6f88 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -3089,6 +3089,7 @@
InputMapper(device),
mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+ mPhysicalWidth(-1), mPhysicalHeight(-1), mPhysicalLeft(0), mPhysicalTop(0),
mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
}
@@ -3596,6 +3597,11 @@
break;
}
+ mPhysicalWidth = naturalPhysicalWidth;
+ mPhysicalHeight = naturalPhysicalHeight;
+ mPhysicalLeft = naturalPhysicalLeft;
+ mPhysicalTop = naturalPhysicalTop;
+
mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
@@ -3604,6 +3610,11 @@
mSurfaceOrientation = mParameters.orientationAware ?
mViewport.orientation : DISPLAY_ORIENTATION_0;
} else {
+ mPhysicalWidth = rawWidth;
+ mPhysicalHeight = rawHeight;
+ mPhysicalLeft = 0;
+ mPhysicalTop = 0;
+
mSurfaceWidth = rawWidth;
mSurfaceHeight = rawHeight;
mSurfaceLeft = 0;
@@ -3914,6 +3925,10 @@
dump += StringPrintf(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
+ dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
+ dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
+ dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
+ dump += StringPrintf(INDENT3 "PhysicalTop: %d\n", mPhysicalTop);
dump += StringPrintf(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
@@ -5118,10 +5133,10 @@
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+ x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale;
y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
- left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
- right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
+ left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
+ right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
orientation -= M_PI;
@@ -5130,10 +5145,10 @@
}
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+ x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale;
y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
- right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
+ left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
+ right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
orientation += M_PI_2;
@@ -6531,8 +6546,12 @@
}
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+ const float scaledX = x * mXScale;
+ const float scaledY = y * mYScale;
return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
- && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
+ && scaledX >= mPhysicalLeft && scaledX <= mPhysicalLeft + mPhysicalWidth
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue
+ && scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
}
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index cef3212..2f98e69 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1517,13 +1517,21 @@
// in the natural orientation.
// The surface origin specifies how the surface coordinates should be translated
// to align with the logical display coordinate space.
- // The orientation may be different from the viewport orientation as it specifies
- // the rotation of the surface coordinates required to produce the viewport's
- // requested orientation, so it will depend on whether the device is orientation aware.
int32_t mSurfaceWidth;
int32_t mSurfaceHeight;
int32_t mSurfaceLeft;
int32_t mSurfaceTop;
+
+ // Similar to the surface coordinates, but in the raw display coordinate space rather than in
+ // the logical coordinate space.
+ int32_t mPhysicalWidth;
+ int32_t mPhysicalHeight;
+ int32_t mPhysicalLeft;
+ int32_t mPhysicalTop;
+
+ // The orientation may be different from the viewport orientation as it specifies
+ // the rotation of the surface coordinates required to produce the viewport's
+ // requested orientation, so it will depend on whether the device is orientation aware.
int32_t mSurfaceOrientation;
// Translation and scaling factors, orientation-independent.
diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS
index d4393d6..81099e8 100644
--- a/services/sensorservice/OWNERS
+++ b/services/sensorservice/OWNERS
@@ -1,2 +1,3 @@
arthuri@google.com
bduddie@google.com
+bstack@google.com
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index d1ea84a..ce4daa5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -8,7 +8,6 @@
"-Wunused",
"-Wunreachable-code",
],
- cppflags: ["-std=c++1z"],
}
cc_defaults {
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 3db633b..f5b5eda 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -704,6 +704,8 @@
}
void BufferLayer::onFirstRef() {
+ Layer::onFirstRef();
+
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cf53930..28b447f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -981,6 +981,21 @@
return NO_ERROR;
}
+status_t SurfaceFlinger::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ if (outViewport == nullptr || display.get() == nullptr) {
+ return BAD_VALUE;
+ }
+
+ sp<const DisplayDevice> device(getDisplayDevice(display));
+ if (device == nullptr) {
+ return BAD_VALUE;
+ }
+
+ *outViewport = device->getViewport();
+
+ return NO_ERROR;
+}
+
int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
if (display == nullptr) {
ALOGE("%s : display is nullptr", __func__);
@@ -2180,11 +2195,15 @@
displayDevice->onSwapBuffersCompleted();
displayDevice->makeCurrent();
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+ sp<Fence> releaseFence = Fence::NO_FENCE;
+
// The layer buffer from the previous frame (if any) is released
// by HWC only when the release fence from this frame (if any) is
// signaled. Always get the release fence from HWC first.
auto hwcLayer = layer->getHwcLayer(hwcId);
- sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+ if (hwcId >= 0) {
+ releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+ }
// If the layer was client composited in the previous frame, we
// need to merge with the previous client target acquire fence.
@@ -2331,8 +2350,10 @@
const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
bool hasWideColorGamut = false;
std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;
+ HdrCapabilities hdrCapabilities;
+ int32_t supportedPerFrameMetadata = 0;
- if (hasWideColorDisplay) {
+ if (hasWideColorDisplay && hwcId >= 0) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
for (ColorMode colorMode : modes) {
switch (colorMode) {
@@ -2351,8 +2372,10 @@
}
}
- HdrCapabilities hdrCapabilities;
- getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);
+ if (hwcId >= 0) {
+ getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);
+ supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(hwcId);
+ }
auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
auto nativeWindow = nativeWindowSurface->getNativeWindow();
@@ -2386,8 +2409,7 @@
new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
dispSurface, std::move(renderSurface), displayWidth, displayHeight,
hasWideColorGamut, hdrCapabilities,
- getHwComposer().getSupportedPerFrameMetadata(hwcId),
- hwcColorModes, initialPowerMode);
+ supportedPerFrameMetadata, hwcColorModes, initialPowerMode);
if (maxFrameBufferAcquiredBuffers >= 3) {
nativeWindowSurface->preallocateBuffers();
@@ -3038,22 +3060,17 @@
}
}
- if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
- // just to be on the safe side, we don't set the
- // scissor on the main display. It should never be needed
- // anyways (though in theory it could since the API allows it).
- const Rect& bounds(displayDevice->getBounds());
- const Rect& scissor(displayDevice->getScissor());
- if (scissor != bounds) {
- // scissor doesn't match the screen's dimensions, so we
- // need to clear everything outside of it and enable
- // the GL scissor so we don't draw anything where we shouldn't
+ const Rect& bounds(displayDevice->getBounds());
+ const Rect& scissor(displayDevice->getScissor());
+ if (scissor != bounds) {
+ // scissor doesn't match the screen's dimensions, so we
+ // need to clear everything outside of it and enable
+ // the GL scissor so we don't draw anything where we shouldn't
- // enable scissor for this frame
- const uint32_t height = displayDevice->getHeight();
- getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
- scissor.getWidth(), scissor.getHeight());
- }
+ // enable scissor for this frame
+ const uint32_t height = displayDevice->getHeight();
+ getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
+ scissor.getWidth(), scissor.getHeight());
}
}
@@ -4821,6 +4838,16 @@
const sp<const DisplayDevice> device(getDisplayDeviceLocked(display));
if (CC_UNLIKELY(device == 0)) return BAD_VALUE;
+ const Rect& dispScissor = device->getScissor();
+ if (!dispScissor.isEmpty()) {
+ sourceCrop.set(dispScissor);
+ // adb shell screencap will default reqWidth and reqHeight to zeros.
+ if (reqWidth == 0 || reqHeight == 0) {
+ reqWidth = uint32_t(device->getViewport().width());
+ reqHeight = uint32_t(device->getViewport().height());
+ }
+ }
+
DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation);
auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8f724e9..0148ab6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -429,6 +429,7 @@
const Rect& sourceCrop, float frameScale, bool childrenOnly);
virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats);
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& display);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
index bef6b7c..b937f41 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
@@ -17,7 +17,6 @@
},
cppflags: [
- "-std=c++1z",
"-Werror",
"-Wno-c++98-compat-pedantic",
"-Wno-disabled-macro-expansion",
diff --git a/services/utils/tests/PriorityDumper_test.cpp b/services/utils/tests/PriorityDumper_test.cpp
index 90cc6de..2320a90 100644
--- a/services/utils/tests/PriorityDumper_test.cpp
+++ b/services/utils/tests/PriorityDumper_test.cpp
@@ -54,7 +54,7 @@
};
static void addAll(Vector<String16>& av, const std::vector<std::string>& v) {
- for (auto element : v) {
+ for (const auto& element : v) {
av.add(String16(element.c_str()));
}
}
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index e4c50d5..09db37a 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -524,8 +524,8 @@
@extension("VK_NV_shading_rate_image") define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
// 166
-@extension("VK_NV_raytracing") define VK_NV_RAYTRACING_SPEC_VERSION 2
-@extension("VK_NV_raytracing") define VK_NV_RAYTRACING_EXTENSION_NAME "VK_NV_raytracing"
+@extension("VK_NV_ray_tracing") define VK_NV_RAY_TRACING_SPEC_VERSION 3
+@extension("VK_NV_ray_tracing") define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing"
// 167
@extension("VK_NV_representative_fragment_test") define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1
@@ -703,7 +703,7 @@
@extension("VK_EXT_validation_cache") @nonDispatchHandle type u64 VkValidationCacheEXT
// 166
-@extension("VK_NV_raytracing") @nonDispatchHandle type u64 VkAccelerationStructureNV
+@extension("VK_NV_ray_tracing") @nonDispatchHandle type u64 VkAccelerationStructureNV
/////////////
// Enums //
@@ -804,7 +804,7 @@
//@extension("VK_EXT_inline_uniform_block") // 139
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
}
@@ -816,7 +816,7 @@
//@extension("VK_EXT_transform_feedback") // 29
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000,
}
@@ -833,7 +833,7 @@
VK_PIPELINE_BIND_POINT_GRAPHICS = 0x00000000,
VK_PIPELINE_BIND_POINT_COMPUTE = 0x00000001,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000,
}
@@ -860,7 +860,7 @@
VK_INDEX_TYPE_UINT16 = 0x00000000,
VK_INDEX_TYPE_UINT32 = 0x00000001,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_INDEX_TYPE_NONE_NV = 1000165000,
}
@@ -1796,7 +1796,7 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001,
VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003,
@@ -2030,7 +2030,7 @@
//@extension("VK_EXT_validation_cache") // 161
VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
}
@@ -2154,7 +2154,7 @@
//@extension("VK_KHR_sampler_ycbcr_conversion") // 157
VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = 1000156000,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000,
}
@@ -2330,32 +2330,32 @@
VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
enum VkRayTracingShaderGroupTypeNV {
VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0,
VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1,
VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = 2,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
enum VkGeometryTypeNV {
VK_GEOMETRY_TYPE_TRIANGLES_NV = 0,
VK_GEOMETRY_TYPE_AABBS_NV = 1,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
enum VkAccelerationStructureTypeNV {
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0,
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
enum VkCopyAccelerationStructureModeNV {
VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0,
VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
enum VkAccelerationStructureMemoryRequirementsTypeNV {
VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0,
VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1,
@@ -2474,7 +2474,7 @@
//@extension("VK_NV_shading_rate_image") // 165
VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000,
VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000,
@@ -2500,7 +2500,7 @@
//@extension("VK_EXT_conditional_rendering") // 82
VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400,
//@extension("VK_EXT_transform_feedback") // 29
@@ -2532,7 +2532,7 @@
VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100,
VK_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200,
VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400,
@@ -2636,7 +2636,7 @@
VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008,
VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = 0x00000010,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020,
}
@@ -2832,7 +2832,7 @@
//@extension("VK_NV_shading_rate_image") // 165
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000,
- //@extension("VK_NV_raytracing") // 166
+ //@extension("VK_NV_ray_tracing") // 166
VK_PIPELINE_STAGE_RAY_TRACING_BIT_NV = 0x00200000,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000,
@@ -2842,6 +2842,9 @@
//@extension("VK_EXT_transform_feedback") // 29
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000,
+
+ //@extension("VK_NV_ray_tracing") // 166
+ VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000,
}
/// Render pass attachment description flags
@@ -3520,17 +3523,17 @@
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
type VkFlags VkGeometryFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
bitfield VkGeometryFlagBitsNV {
VK_GEOMETRY_OPAQUE_BIT_NV = 0x00000001,
VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = 0x00000002,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
type VkFlags VkGeometryInstanceFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
bitfield VkGeometryInstanceFlagBitsNV {
VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002,
@@ -3538,9 +3541,9 @@
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008,
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
type VkFlags VkBuildAccelerationStructureFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
bitfield VkBuildAccelerationStructureFlagBitsNV {
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = 0x00000001,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = 0x00000002,
@@ -7276,7 +7279,7 @@
const VkCoarseSampleOrderCustomNV* pCustomSampleOrders
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkRayTracingShaderGroupCreateInfoNV {
VkStructureType sType
const void* pNext
@@ -7287,7 +7290,7 @@
u32 intersectionShader
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkRayTracingPipelineCreateInfoNV {
VkStructureType sType
const void* pNext
@@ -7302,7 +7305,7 @@
s32 basePipelineIndex
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkGeometryTrianglesNV {
VkStructureType sType
const void* pNext
@@ -7319,7 +7322,7 @@
VkDeviceSize transformOffset
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkGeometryAABBNV {
VkStructureType sType
const void* pNext
@@ -7329,13 +7332,13 @@
VkDeviceSize offset
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkGeometryDataNV {
VkGeometryTrianglesNV triangles
VkGeometryAABBNV aabbs
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkGeometryNV {
VkStructureType sType
const void* pNext
@@ -7344,7 +7347,7 @@
VkGeometryFlagsNV flags
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkAccelerationStructureInfoNV {
VkStructureType sType
const void* pNext
@@ -7355,7 +7358,7 @@
const VkGeometryNV* pGeometries
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkAccelerationStructureCreateInfoNV {
VkStructureType sType
const void* pNext
@@ -7363,7 +7366,7 @@
VkAccelerationStructureInfoNV info
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkBindAccelerationStructureMemoryInfoNV {
VkStructureType sType
const void* pNext
@@ -7374,7 +7377,7 @@
const u32* pDeviceIndices
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkDescriptorAccelerationStructureInfoNV {
VkStructureType sType
const void* pNext
@@ -7382,7 +7385,7 @@
const VkAccelerationStructureNV* pAccelerationStructures
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkAccelerationStructureMemoryRequirementsInfoNV {
VkStructureType sType
const void* pNext
@@ -7390,7 +7393,7 @@
VkAccelerationStructureNV accelerationStructure
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
class VkPhysicalDeviceRaytracingPropertiesNV {
VkStructureType sType
void* pNext
@@ -11502,7 +11505,7 @@
const VkCoarseSampleOrderCustomNV* pCustomSampleOrders) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkCreateAccelerationStructureNV(
VkDevice device,
const VkAccelerationStructureCreateInfoNV* pCreateInfo,
@@ -11511,21 +11514,21 @@
return ?
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkDestroyAccelerationStructureNV(
VkDevice device,
VkAccelerationStructureNV accelerationStructure,
const VkAllocationCallbacks* pAllocator) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkGetAccelerationStructureMemoryRequirementsNV(
VkDevice device,
const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo,
VkMemoryRequirements2KHR* pMemoryRequirements) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkBindAccelerationStructureMemoryNV(
VkDevice device,
u32 bindInfoCount,
@@ -11533,7 +11536,7 @@
return ?
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkCmdBuildAccelerationStructureNV(
VkCommandBuffer commandBuffer,
const VkAccelerationStructureInfoNV* pInfo,
@@ -11546,7 +11549,7 @@
VkDeviceSize scratchOffset) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkCmdCopyAccelerationStructureNV(
VkCommandBuffer commandBuffer,
VkAccelerationStructureNV dst,
@@ -11554,7 +11557,7 @@
VkCopyAccelerationStructureModeNV mode) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkCmdTraceRaysNV(
VkCommandBuffer commandBuffer,
VkBuffer raygenShaderBindingTableBuffer,
@@ -11573,7 +11576,7 @@
u32 depth) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkCreateRaytracingPipelinesNV(
VkDevice device,
VkPipelineCache pipelineCache,
@@ -11584,7 +11587,7 @@
return ?
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkGetRaytracingShaderHandlesNV(
VkDevice device,
VkPipeline pipeline,
@@ -11595,7 +11598,7 @@
return ?
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkGetAccelerationStructureHandleNV(
VkDevice device,
VkAccelerationStructureNV accelerationStructure,
@@ -11604,7 +11607,7 @@
return ?
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd void vkCmdWriteAccelerationStructurePropertiesNV(
VkCommandBuffer commandBuffer,
u32 accelerationStructureCount,
@@ -11614,7 +11617,7 @@
u32 firstQuery) {
}
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
cmd VkResult vkCompileDeferredNV(
VkDevice device,
VkPipeline pipeline,
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 7eaf7b2..fed8481 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -39,6 +39,9 @@
"-Wno-switch-enum",
"-Wno-undef",
+ // Have clang emit complete debug_info.
+ "-fstandalone-debug",
+
//"-DLOG_NDEBUG=0",
],