Merge "update cas plugin interface for cas@1.2"
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 09aee89..be7e3e1 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -66,7 +66,6 @@
name: "dumpstate_aidl",
srcs: [
"binder/android/os/IDumpstateListener.aidl",
- "binder/android/os/IDumpstateToken.aidl",
"binder/android/os/IDumpstate.aidl",
],
path: "binder",
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index f98df99..ccd74db 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -58,8 +58,6 @@
exit(0);
}
-class DumpstateToken : public BnDumpstateToken {};
-
} // namespace
DumpstateService::DumpstateService() : ds_(nullptr) {
@@ -81,38 +79,6 @@
return android::OK;
}
-// Note: this method is part of the old flow and is not expected to be used in combination
-// with startBugreport.
-binder::Status DumpstateService::setListener(const std::string& name,
- const sp<IDumpstateListener>& listener,
- bool getSectionDetails,
- sp<IDumpstateToken>* returned_token) {
- *returned_token = nullptr;
- if (name.empty()) {
- MYLOGE("setListener(): name not set\n");
- return binder::Status::ok();
- }
- if (listener == nullptr) {
- MYLOGE("setListener(): listener not set\n");
- return binder::Status::ok();
- }
- std::lock_guard<std::mutex> lock(lock_);
- if (ds_ == nullptr) {
- ds_ = &(Dumpstate::GetInstance());
- }
- if (ds_->listener_ != nullptr) {
- MYLOGE("setListener(%s): already set (%s)\n", name.c_str(), ds_->listener_name_.c_str());
- return binder::Status::ok();
- }
-
- ds_->listener_name_ = name;
- ds_->listener_ = listener;
- ds_->report_section_ = getSectionDetails;
- *returned_token = new DumpstateToken();
-
- return binder::Status::ok();
-}
-
binder::Status DumpstateService::startBugreport(int32_t calling_uid,
const std::string& calling_package,
const android::base::unique_fd& bugreport_fd,
@@ -121,8 +87,7 @@
const sp<IDumpstateListener>& listener) {
MYLOGI("startBugreport() with mode: %d\n", bugreport_mode);
- // This is the bugreporting API flow, so ensure there is only one bugreport in progress at a
- // time.
+ // Ensure there is only one bugreport in progress at a time.
std::lock_guard<std::mutex> lock(lock_);
if (ds_ != nullptr) {
MYLOGE("Error! There is already a bugreport in progress. Returning.");
@@ -204,19 +169,17 @@
dprintf(fd, "progress:\n");
ds_->progress_->Dump(fd, " ");
dprintf(fd, "args: %s\n", ds_->options_->args.c_str());
- dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str());
+ dprintf(fd, "bugreport_mode: %s\n", ds_->options_->bugreport_mode.c_str());
dprintf(fd, "version: %s\n", ds_->version_.c_str());
dprintf(fd, "bugreport_dir: %s\n", destination.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());
dprintf(fd, "path: %s\n", ds_->path_.c_str());
- dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str());
dprintf(fd, "base_name: %s\n", ds_->base_name_.c_str());
dprintf(fd, "name: %s\n", ds_->name_.c_str());
dprintf(fd, "now: %ld\n", ds_->now_);
dprintf(fd, "is_zipping: %s\n", ds_->IsZipping() ? "true" : "false");
- dprintf(fd, "listener: %s\n", ds_->listener_name_.c_str());
dprintf(fd, "notification title: %s\n", ds_->options_->notification_title.c_str());
dprintf(fd, "notification description: %s\n", ds_->options_->notification_description.c_str());
diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h
index 68eda47..27954ad 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -24,7 +24,6 @@
#include <binder/BinderService.h>
#include "android/os/BnDumpstate.h"
-#include "android/os/BnDumpstateToken.h"
#include "dumpstate.h"
namespace android {
@@ -38,9 +37,6 @@
static char const* getServiceName();
status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status setListener(const std::string& name, const sp<IDumpstateListener>& listener,
- bool getSectionDetails,
- sp<IDumpstateToken>* returned_token) override;
binder::Status startBugreport(int32_t calling_uid, const std::string& calling_package,
const android::base::unique_fd& bugreport_fd,
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index cb2d8b8..3f359c8 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -17,24 +17,12 @@
package android.os;
import android.os.IDumpstateListener;
-import android.os.IDumpstateToken;
/**
* Binder interface for the currently running dumpstate process.
* {@hide}
*/
interface IDumpstate {
- // TODO: remove method once startBugReport is used by Shell.
- /*
- * Sets the listener for this dumpstate progress.
- *
- * Returns a token used to monitor dumpstate death, or `nullptr` if the listener was already
- * set (the listener behaves like a Highlander: There Can be Only One).
- * Set {@code getSectionDetails} to true in order to receive callbacks with per section
- * progress details
- */
- IDumpstateToken setListener(@utf8InCpp String name, IDumpstateListener listener,
- boolean getSectionDetails);
// NOTE: If you add to or change these modes, please also change the corresponding enums
// in system server, in BugreportParams.java.
diff --git a/cmds/dumpstate/binder/android/os/IDumpstateToken.aidl b/cmds/dumpstate/binder/android/os/IDumpstateToken.aidl
deleted file mode 100644
index 7f74ceb..0000000
--- a/cmds/dumpstate/binder/android/os/IDumpstateToken.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/**
- * Token used by the IDumpstateListener to watch for dumpstate death.
- * {@hide}
- */
-interface IDumpstateToken {
-}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b87582e..5469d0c 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -231,14 +231,6 @@
return true;
}
-static bool IsFileEmpty(const std::string& file_path) {
- std::ifstream file(file_path, std::ios::binary | std::ios::ate);
- if(file.bad()) {
- MYLOGE("Cannot open file: %s\n", file_path.c_str());
- return true;
- }
- return file.tellg() <= 0;
-}
int64_t GetModuleMetadataVersion() {
auto binder = defaultServiceManager()->getService(android::String16("package_native"));
@@ -288,11 +280,8 @@
};
static const int NUM_OF_DUMPS = arraysize(kDumpstateBoardFiles);
-static constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
static constexpr char PROPERTY_VERSION[] = "dumpstate.version";
-static constexpr char PROPERTY_EXTRA_TITLE[] = "dumpstate.options.title";
-static constexpr char PROPERTY_EXTRA_DESCRIPTION[] = "dumpstate.options.description";
static const CommandOptions AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot().Build();
@@ -696,8 +685,8 @@
RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
CommandOptions::WithTimeout(1).Always().Build());
printf("Bugreport format version: %s\n", version_.c_str());
- printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
- PropertiesHelper::IsDryRun(), options_->args.c_str(), options_->extra_options.c_str());
+ printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s bugreport_mode=%s\n", id_, pid_,
+ PropertiesHelper::IsDryRun(), options_->args.c_str(), options_->bugreport_mode.c_str());
printf("\n");
}
@@ -960,6 +949,7 @@
}
RunCommand("LPDUMP", {"lpdump", "--all"});
+ RunCommand("DEVICE-MAPPER", {"gsid", "dump-device-mapper"});
}
static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_dir) {
@@ -1905,7 +1895,7 @@
static void ShowUsage() {
fprintf(stderr,
"usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-d] [-p] "
- "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n"
+ "[-z]] [-s] [-S] [-q] [-P] [-R] [-V version]\n"
" -h: display this help message\n"
" -b: play sound file instead of vibrate, at beginning of job\n"
" -e: play sound file instead of vibrate, at end of job\n"
@@ -1915,11 +1905,8 @@
" -s: write output to control socket (for init)\n"
" -S: write file location to control socket (for init; requires -z)\n"
" -q: disable vibrate\n"
- " -B: send broadcast when finished\n"
- " -P: send broadcast when started and update system properties on "
- "progress (requires -B)\n"
- " -R: take bugreport in remote mode (requires -z, -d and -B, "
- "shouldn't be used with -P)\n"
+ " -P: send broadcast when started and do progress updates\n"
+ " -R: take bugreport in remote mode (requires -z and -d, shouldn't be used with -P)\n"
" -w: start binder service and make it wait for a call to startBugreport\n"
" -v: prints the dumpstate header and exit\n");
}
@@ -1976,41 +1963,6 @@
return true;
}
-static std::string SHA256_file_hash(const std::string& filepath) {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK
- | O_CLOEXEC | O_NOFOLLOW)));
- if (fd == -1) {
- MYLOGE("open(%s): %s\n", filepath.c_str(), strerror(errno));
- return nullptr;
- }
-
- SHA256_CTX ctx;
- SHA256_Init(&ctx);
-
- std::vector<uint8_t> buffer(65536);
- while (1) {
- ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size()));
- if (bytes_read == 0) {
- break;
- } else if (bytes_read == -1) {
- MYLOGE("read(%s): %s\n", filepath.c_str(), strerror(errno));
- return nullptr;
- }
-
- SHA256_Update(&ctx, buffer.data(), bytes_read);
- }
-
- uint8_t hash[SHA256_DIGEST_LENGTH];
- SHA256_Final(hash, &ctx);
-
- char hash_buffer[SHA256_DIGEST_LENGTH * 2 + 1];
- for(size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- sprintf(hash_buffer + (i * 2), "%02x", hash[i]);
- }
- hash_buffer[sizeof(hash_buffer) - 1] = 0;
- return std::string(hash_buffer);
-}
-
static void SendBroadcast(const std::string& action, const std::vector<std::string>& args) {
// clang-format off
std::vector<std::string> am = {"/system/bin/cmd", "activity", "broadcast", "--user", "0",
@@ -2103,37 +2055,10 @@
}
/*
- * Finalizes writing to the file by renaming or zipping the tmp file to the final location,
+ * Finalizes writing to the file by zipping the tmp file to the final location,
* printing zipped file status, etc.
*/
static void FinalizeFile() {
- /* check if user changed the suffix using system properties */
- std::string name =
- android::base::GetProperty(android::base::StringPrintf("dumpstate.%d.name", ds.pid_), "");
- bool change_suffix = false;
- if (!name.empty()) {
- /* must whitelist which characters are allowed, otherwise it could cross directories */
- std::regex valid_regex("^[-_a-zA-Z0-9]+$");
- if (std::regex_match(name.c_str(), valid_regex)) {
- change_suffix = true;
- } else {
- MYLOGE("invalid suffix provided by user: %s\n", name.c_str());
- }
- }
- if (change_suffix) {
- MYLOGI("changing suffix from %s to %s\n", ds.name_.c_str(), name.c_str());
- ds.name_ = name;
- if (!ds.screenshot_path_.empty()) {
- std::string new_screenshot_path = ds.GetPath(ds.CalledByApi() ? "-tmp.png" : ".png");
- if (rename(ds.screenshot_path_.c_str(), new_screenshot_path.c_str())) {
- MYLOGE("rename(%s, %s): %s\n", ds.screenshot_path_.c_str(),
- new_screenshot_path.c_str(), strerror(errno));
- } else {
- ds.screenshot_path_ = new_screenshot_path;
- }
- }
- }
-
bool do_text_file = true;
if (ds.options_->do_zip_file) {
if (!ds.FinishZipFile()) {
@@ -2141,25 +2066,6 @@
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(ds.CalledByApi() ? "-tmp.zip" : ".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;
- }
- }
- }
- }
- if (do_text_file) {
- ds.path_ = ds.GetPath(".txt");
- MYLOGD("Generating .txt bugreport at %s from %s\n", ds.path_.c_str(), ds.tmp_path_.c_str());
- if (rename(ds.tmp_path_.c_str(), ds.path_.c_str())) {
- MYLOGE("rename(%s, %s): %s\n", ds.tmp_path_.c_str(), ds.path_.c_str(), strerror(errno));
- ds.path_.clear();
}
}
if (ds.options_->use_control_socket) {
@@ -2174,49 +2080,6 @@
}
}
-/* Broadcasts that we are done with the bugreport */
-static void SendBugreportFinishedBroadcast() {
- // TODO(b/111441001): use callback instead of broadcast.
- if (!ds.path_.empty()) {
- MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
- // clang-format off
-
- std::vector<std::string> am_args = {
- "--receiver-permission", "android.permission.DUMP",
- "--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.DUMPSTATE_LOG", ds.log_path_
- };
- // clang-format on
- if (ds.options_->do_fb && !android::os::IsFileEmpty(ds.screenshot_path_)) {
- am_args.push_back("--es");
- am_args.push_back("android.intent.extra.SCREENSHOT");
- am_args.push_back(ds.screenshot_path_);
- }
- if (!ds.options_->notification_title.empty()) {
- am_args.push_back("--es");
- am_args.push_back("android.intent.extra.TITLE");
- am_args.push_back(ds.options_->notification_title);
- if (!ds.options_->notification_description.empty()) {
- am_args.push_back("--es");
- am_args.push_back("android.intent.extra.DESCRIPTION");
- am_args.push_back(ds.options_->notification_description);
- }
- }
- 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_));
- SendBroadcast("com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
- } else {
- SendBroadcast("com.android.internal.intent.action.BUGREPORT_FINISHED", am_args);
- }
- } else {
- MYLOGE("Skipping finished broadcast because bugreport could not be generated\n");
- }
-}
static inline const char* ModeToString(Dumpstate::BugreportMode mode) {
switch (mode) {
@@ -2238,10 +2101,9 @@
}
static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options) {
- options->extra_options = ModeToString(mode);
+ options->bugreport_mode = ModeToString(mode);
switch (mode) {
case Dumpstate::BugreportMode::BUGREPORT_FULL:
- options->do_broadcast = true;
options->do_fb = true;
break;
case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
@@ -2249,88 +2111,32 @@
options->do_start_service = true;
options->do_progress_updates = true;
options->do_fb = false;
- options->do_broadcast = true;
break;
case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
options->do_vibrate = false;
options->is_remote_mode = true;
options->do_fb = false;
- options->do_broadcast = true;
break;
case Dumpstate::BugreportMode::BUGREPORT_WEAR:
options->do_start_service = true;
options->do_progress_updates = true;
options->do_zip_file = true;
options->do_fb = true;
- options->do_broadcast = true;
break;
case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
options->telephony_only = true;
options->do_fb = false;
- options->do_broadcast = true;
break;
case Dumpstate::BugreportMode::BUGREPORT_WIFI:
options->wifi_only = true;
options->do_zip_file = true;
options->do_fb = false;
- 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 default bugreport.
- Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
-
- std::string extra_options = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
- if (!extra_options.empty()) {
- // Framework uses a system property to override some command-line args.
- // 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") {
- mode = Dumpstate::BugreportMode::BUGREPORT_WEAR;
- } else if (extra_options == "bugreporttelephony") {
- mode = Dumpstate::BugreportMode::BUGREPORT_TELEPHONY;
- } else if (extra_options == "bugreportwifi") {
- mode = Dumpstate::BugreportMode::BUGREPORT_WIFI;
- } else {
- MYLOGE("Unknown extra option: %s\n", extra_options.c_str());
- }
- // Reset the property
- android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
- }
- return mode;
-}
-
-// TODO: Move away from system properties when we have options passed via binder calls.
-/* Sets runtime options from the system properties and then clears those properties. */
-static void SetOptionsFromProperties(Dumpstate::DumpOptions* options) {
- Dumpstate::BugreportMode mode = getBugreportModeFromProperty();
- SetOptionsFromMode(mode, options);
-
- options->notification_title = android::base::GetProperty(PROPERTY_EXTRA_TITLE, "");
- if (!options->notification_title.empty()) {
- // Reset the property
- android::base::SetProperty(PROPERTY_EXTRA_TITLE, "");
-
- options->notification_description =
- android::base::GetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
- if (!options->notification_description.empty()) {
- // Reset the property
- android::base::SetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
- }
- MYLOGD("notification (title: %s, description: %s)\n", options->notification_title.c_str(),
- options->notification_description.c_str());
- }
-}
-
static void LogDumpOptions(const Dumpstate::DumpOptions& options) {
MYLOGI("do_zip_file: %d\n", options.do_zip_file);
MYLOGI("do_add_date: %d\n", options.do_add_date);
@@ -2338,7 +2144,6 @@
MYLOGI("use_socket: %d\n", options.use_socket);
MYLOGI("use_control_socket: %d\n", options.use_control_socket);
MYLOGI("do_fb: %d\n", options.do_fb);
- MYLOGI("do_broadcast: %d\n", options.do_broadcast);
MYLOGI("is_remote_mode: %d\n", options.is_remote_mode);
MYLOGI("show_header_only: %d\n", options.show_header_only);
MYLOGI("do_start_service: %d\n", options.do_start_service);
@@ -2346,10 +2151,8 @@
MYLOGI("wifi_only: %d\n", options.wifi_only);
MYLOGI("do_progress_updates: %d\n", options.do_progress_updates);
MYLOGI("fd: %d\n", options.bugreport_fd.get());
- MYLOGI("extra_options: %s\n", options.extra_options.c_str());
+ MYLOGI("bugreport_mode: %s\n", options.bugreport_mode.c_str());
MYLOGI("args: %s\n", options.args.c_str());
- MYLOGI("notification_title: %s\n", options.notification_title.c_str());
- MYLOGI("notification_description: %s\n", options.notification_description.c_str());
}
void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
@@ -2364,7 +2167,6 @@
bugreport_fd.reset(dup(bugreport_fd_in.get()));
screenshot_fd.reset(dup(screenshot_fd_in.get()));
- extra_options = ModeToString(bugreport_mode);
SetOptionsFromMode(bugreport_mode, this);
}
@@ -2383,7 +2185,6 @@
case 'p': do_fb = true; break;
case 'P': do_progress_updates = true; break;
case 'R': is_remote_mode = true; break;
- case 'B': do_broadcast = true; break;
case 'V': break; // compatibility no-op
case 'w':
// This was already processed
@@ -2409,7 +2210,6 @@
// Reset next index used by getopt so this can be called multiple times, for eg, in tests.
optind = 1;
- SetOptionsFromProperties(this);
return status;
}
@@ -2418,7 +2218,7 @@
return false;
}
- if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast) && !OutputToFile()) {
+ if ((do_zip_file || do_add_date || do_progress_updates) && !OutputToFile()) {
return false;
}
@@ -2426,11 +2226,7 @@
return false;
}
- if (do_progress_updates && !do_broadcast) {
- return false;
- }
-
- if (is_remote_mode && (do_progress_updates || !do_broadcast || !do_zip_file || !do_add_date)) {
+ if (is_remote_mode && (do_progress_updates || !do_zip_file || !do_add_date)) {
return false;
}
return true;
@@ -2528,7 +2324,7 @@
MYLOGD("dumpstate calling_uid = %d ; calling package = %s \n",
calling_uid, calling_package.c_str());
- if (options_->bugreport_fd.get() != -1) {
+ if (CalledByApi()) {
// If the output needs to be copied over to the caller's fd, get user consent.
android::String16 package(calling_package.c_str());
CheckUserConsent(calling_uid, package);
@@ -2573,8 +2369,8 @@
MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
}
- MYLOGI("dumpstate info: id=%d, args='%s', extra_options= %s)\n", id_, options_->args.c_str(),
- options_->extra_options.c_str());
+ MYLOGI("dumpstate info: id=%d, args='%s', bugreport_mode= %s)\n", id_, options_->args.c_str(),
+ options_->bugreport_mode.c_str());
MYLOGI("bugreport format version: %s\n", version_.c_str());
@@ -2601,18 +2397,13 @@
PrepareToWriteToFile();
if (options_->do_progress_updates) {
- if (options_->do_broadcast) {
- // clang-format off
- std::vector<std::string> am_args = {
- "--receiver-permission", "android.permission.DUMP",
- "--es", "android.intent.extra.NAME", name_,
- "--ei", "android.intent.extra.ID", std::to_string(id_),
- "--ei", "android.intent.extra.PID", std::to_string(pid_),
- "--ei", "android.intent.extra.MAX", std::to_string(progress_->GetMax()),
- };
- // clang-format on
- SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
- }
+ // clang-format off
+ std::vector<std::string> am_args = {
+ "--receiver-permission", "android.permission.DUMP",
+ };
+ // clang-format on
+ // Send STARTED broadcast for apps that listen to bugreport generation events
+ SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
if (options_->use_control_socket) {
dprintf(control_socket_fd_, "BEGIN:%s\n", path_.c_str());
}
@@ -2700,14 +2491,14 @@
TEMP_FAILURE_RETRY(dup2(dup_stdout_fd, fileno(stdout)));
}
- // Rename, and/or zip the (now complete) .tmp file within the internal directory.
+ // Zip the (now complete) .tmp file within the internal directory.
if (options_->OutputToFile()) {
FinalizeFile();
}
// Share the final file with the caller if the user has consented or Shell is the caller.
Dumpstate::RunStatus status = Dumpstate::RunStatus::OK;
- if (options_->bugreport_fd.get() != -1) {
+ if (CalledByApi()) {
status = CopyBugreportIfUserConsented(calling_uid);
if (status != Dumpstate::RunStatus::OK &&
status != Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT) {
@@ -2748,12 +2539,6 @@
}
}
- /* tell activity manager we're done */
- if (options_->do_broadcast && !CalledByApi()) {
- SendBugreportFinishedBroadcast();
- // Note that listener_ is notified in Run();
- }
-
MYLOGD("Final progress: %d/%d (estimated %d)\n", progress_->Get(), progress_->GetMax(),
progress_->GetInitialMax());
progress_->Save();
@@ -3686,13 +3471,11 @@
if (listener_ != nullptr) {
if (percent % 5 == 0) {
// We don't want to spam logcat, so only log multiples of 5.
- MYLOGD("Setting progress (%s): %d/%d (%d%%)\n", listener_name_.c_str(), progress, max,
- percent);
+ MYLOGD("Setting progress: %d/%d (%d%%)\n", progress, max, percent);
} else {
// stderr is ignored on normal invocations, but useful when calling
// /system/bin/dumpstate directly for debuggging.
- fprintf(stderr, "Setting progress (%s): %d/%d (%d%%)\n", listener_name_.c_str(),
- progress, max, percent);
+ fprintf(stderr, "Setting progress: %d/%d (%d%%)\n", progress, max, percent);
}
listener_->onProgress(percent);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 430936e..831574d 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -359,7 +359,6 @@
bool use_socket = false;
bool use_control_socket = false;
bool do_fb = false;
- bool do_broadcast = false;
bool is_remote_mode = false;
bool show_header_only = false;
bool do_start_service = false;
@@ -371,16 +370,15 @@
android::base::unique_fd bugreport_fd;
// File descriptor to screenshot file.
android::base::unique_fd screenshot_fd;
- // TODO: rename to MODE.
- // Extra options passed as system property.
- std::string extra_options;
+ // Bugreport mode of the bugreport.
+ std::string bugreport_mode;
// Command-line arguments as string
std::string args;
// Notification title and description
std::string notification_title;
std::string notification_description;
- /* Initializes options from commandline arguments and system properties. */
+ /* Initializes options from commandline arguments. */
RunStatus Initialize(int argc, char* argv[]);
/* Initializes options from the requested mode. */
@@ -456,8 +454,6 @@
// Binder object listening to progress.
android::sp<android::os::IDumpstateListener> listener_;
- std::string listener_name_;
- bool report_section_;
// List of open tombstone dump files.
std::vector<DumpData> tombstone_data_;
diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
index fbb01f5..f1884f8 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -195,7 +195,6 @@
static Dumpstate& ds;
static std::chrono::milliseconds duration;
static void SetUpTestCase() {
- property_set("dumpstate.options", "bugreportplus");
// clang-format off
char* argv[] = {
(char*)"dumpstate",
@@ -206,8 +205,6 @@
// clang-format on
sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout)), sections));
ds.listener_ = listener;
- ds.listener_name_ = "Smokey";
- ds.report_section_ = true;
auto start = std::chrono::steady_clock::now();
ds.ParseCommandlineAndRun(ARRAY_SIZE(argv), argv);
auto end = std::chrono::steady_clock::now();
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index cff1d43..1ae073c 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -37,6 +37,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/properties.h>
+#include <android-base/unique_fd.h>
namespace android {
namespace os {
@@ -148,10 +149,9 @@
options_ = Dumpstate::DumpOptions();
}
void TearDown() {
- // Reset the property
- property_set("dumpstate.options", "");
}
Dumpstate::DumpOptions options_;
+ android::base::unique_fd fd;
};
TEST_F(DumpOptionsTest, InitializeNone) {
@@ -174,7 +174,6 @@
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) {
@@ -200,7 +199,6 @@
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);
}
@@ -226,28 +224,13 @@
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"),
- };
- // clang-format on
- property_set("dumpstate.options", "bugreportfull");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd);
EXPECT_TRUE(options_.do_add_date);
EXPECT_TRUE(options_.do_fb);
EXPECT_TRUE(options_.do_zip_file);
- EXPECT_TRUE(options_.do_broadcast);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -260,23 +243,8 @@
}
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"),
- };
- // clang-format on
-
- property_set("dumpstate.options", "bugreportplus");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd);
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);
@@ -291,23 +259,8 @@
}
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"),
- };
- // clang-format on
-
- property_set("dumpstate.options", "bugreportremote");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd);
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);
@@ -321,24 +274,9 @@
}
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"),
- };
- // clang-format on
-
- property_set("dumpstate.options", "bugreportwear");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd);
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);
@@ -352,24 +290,9 @@
}
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"),
- };
- // clang-format on
-
- property_set("dumpstate.options", "bugreporttelephony");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd);
EXPECT_TRUE(options_.do_add_date);
EXPECT_FALSE(options_.do_fb);
- EXPECT_TRUE(options_.do_broadcast);
EXPECT_TRUE(options_.do_zip_file);
EXPECT_TRUE(options_.telephony_only);
@@ -383,24 +306,9 @@
}
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"),
- };
- // clang-format on
-
- property_set("dumpstate.options", "bugreportwifi");
-
- Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
-
- EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd);
EXPECT_TRUE(options_.do_add_date);
EXPECT_FALSE(options_.do_fb);
- EXPECT_TRUE(options_.do_broadcast);
EXPECT_TRUE(options_.do_zip_file);
EXPECT_TRUE(options_.wifi_only);
@@ -420,20 +328,15 @@
const_cast<char*>("bugreport"),
const_cast<char*>("-d"),
const_cast<char*>("-p"),
- const_cast<char*>("-B"),
const_cast<char*>("-z"),
};
// 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);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -472,7 +375,6 @@
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, InitializePartial2) {
@@ -484,7 +386,6 @@
const_cast<char*>("-p"),
const_cast<char*>("-P"),
const_cast<char*>("-R"),
- const_cast<char*>("-B"),
};
// clang-format on
@@ -496,7 +397,6 @@
EXPECT_TRUE(options_.do_fb);
EXPECT_TRUE(options_.do_progress_updates);
EXPECT_TRUE(options_.is_remote_mode);
- EXPECT_TRUE(options_.do_broadcast);
// Other options retain default values
EXPECT_FALSE(options_.do_add_date);
@@ -544,7 +444,7 @@
}
TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
- options_.do_broadcast = true;
+ options_.do_progress_updates = true;
// Writing to socket = !writing to file.
options_.use_socket = true;
EXPECT_FALSE(options_.ValidateOptions());
@@ -561,19 +461,10 @@
EXPECT_TRUE(options_.ValidateOptions());
}
-TEST_F(DumpOptionsTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
- options_.do_progress_updates = true;
- EXPECT_FALSE(options_.ValidateOptions());
-
- options_.do_broadcast = true;
- EXPECT_TRUE(options_.ValidateOptions());
-}
-
TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
options_.is_remote_mode = true;
EXPECT_FALSE(options_.ValidateOptions());
- options_.do_broadcast = true;
options_.do_zip_file = true;
options_.do_add_date = true;
EXPECT_TRUE(options_.ValidateOptions());
@@ -616,8 +507,8 @@
ds.progress_.reset(new Progress(initial_max, progress, 1.2));
}
- std::string GetProgressMessage(const std::string& listener_name, int progress, int max,
- int old_max = 0, bool update_progress = true) {
+ std::string GetProgressMessage(int progress, int max,
+ int old_max = 0, bool update_progress = true) {
EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
EXPECT_EQ(max, ds.progress_->GetMax()) << "invalid max";
@@ -630,9 +521,8 @@
}
if (update_progress) {
- message += android::base::StringPrintf("Setting progress (%s): %d/%d (%d%%)\n",
- listener_name.c_str(), progress, max,
- (100 * progress / max));
+ message += android::base::StringPrintf("Setting progress: %d/%d (%d%%)\n",
+ progress, max, (100 * progress / max));
}
return message;
@@ -787,18 +677,17 @@
TEST_F(DumpstateTest, RunCommandProgress) {
sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
ds.listener_ = listener;
- ds.listener_name_ = "FoxMulder";
SetProgress(0, 30);
EXPECT_CALL(*listener, onProgress(66)); // 20/30 %
EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(20).Build()));
- std::string progress_message = GetProgressMessage(ds.listener_name_, 20, 30);
+ std::string progress_message = GetProgressMessage(20, 30);
EXPECT_THAT(out, StrEq("stdout\n"));
EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
EXPECT_CALL(*listener, onProgress(80)); // 24/30 %
EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(4).Build()));
- progress_message = GetProgressMessage(ds.listener_name_, 24, 30);
+ progress_message = GetProgressMessage(24, 30);
EXPECT_THAT(out, StrEq("stdout\n"));
EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
@@ -806,20 +695,20 @@
SetDryRun(true);
EXPECT_CALL(*listener, onProgress(90)); // 27/30 %
EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(3).Build()));
- progress_message = GetProgressMessage(ds.listener_name_, 27, 30);
+ progress_message = GetProgressMessage(27, 30);
EXPECT_THAT(out, IsEmpty());
EXPECT_THAT(err, StrEq(progress_message));
SetDryRun(false);
EXPECT_CALL(*listener, onProgress(96)); // 29/30 %
EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(2).Build()));
- progress_message = GetProgressMessage(ds.listener_name_, 29, 30);
+ progress_message = GetProgressMessage(29, 30);
EXPECT_THAT(out, StrEq("stdout\n"));
EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
EXPECT_CALL(*listener, onProgress(100)); // 30/30 %
EXPECT_EQ(0, RunCommand("", {kSimpleCommand}, CommandOptions::WithTimeout(1).Build()));
- progress_message = GetProgressMessage(ds.listener_name_, 30, 30);
+ progress_message = GetProgressMessage(30, 30);
EXPECT_THAT(out, StrEq("stdout\n"));
EXPECT_THAT(err, StrEq("stderr\n" + progress_message));
@@ -1044,14 +933,12 @@
TEST_F(DumpstateTest, DumpFileUpdateProgress) {
sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
ds.listener_ = listener;
- ds.listener_name_ = "FoxMulder";
SetProgress(0, 30);
EXPECT_CALL(*listener, onProgress(16)); // 5/30 %
EXPECT_EQ(0, DumpFile("", kTestDataPath + "single-line.txt"));
- std::string progress_message =
- GetProgressMessage(ds.listener_name_, 5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
+ std::string progress_message = GetProgressMessage(5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
EXPECT_THAT(err, StrEq(progress_message));
EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
@@ -1063,48 +950,6 @@
DumpstateService dss;
};
-TEST_F(DumpstateServiceTest, SetListenerNoName) {
- sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
- sp<IDumpstateToken> token;
- EXPECT_TRUE(dss.setListener("", listener, /* getSectionDetails = */ false, &token).isOk());
- ASSERT_THAT(token, IsNull());
-}
-
-TEST_F(DumpstateServiceTest, SetListenerNoPointer) {
- sp<IDumpstateToken> token;
- EXPECT_TRUE(
- dss.setListener("whatever", nullptr, /* getSectionDetails = */ false, &token).isOk());
- ASSERT_THAT(token, IsNull());
-}
-
-TEST_F(DumpstateServiceTest, SetListenerTwice) {
- sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
- sp<IDumpstateToken> token;
- EXPECT_TRUE(
- dss.setListener("whatever", listener, /* getSectionDetails = */ false, &token).isOk());
- ASSERT_THAT(token, NotNull());
- EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
- EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
-
- token.clear();
- EXPECT_TRUE(
- dss.setListener("whatsoever", listener, /* getSectionDetails = */ false, &token).isOk());
- ASSERT_THAT(token, IsNull());
- EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
- EXPECT_FALSE(Dumpstate::GetInstance().report_section_);
-}
-
-TEST_F(DumpstateServiceTest, SetListenerWithSectionDetails) {
- sp<DumpstateListenerMock> listener(new DumpstateListenerMock());
- sp<IDumpstateToken> token;
- Dumpstate::GetInstance().listener_ = nullptr;
- EXPECT_TRUE(
- dss.setListener("whatever", listener, /* getSectionDetails = */ true, &token).isOk());
- ASSERT_THAT(token, NotNull());
- EXPECT_THAT(Dumpstate::GetInstance().listener_name_, StrEq("whatever"));
- EXPECT_TRUE(Dumpstate::GetInstance().report_section_);
-}
-
class ProgressTest : public DumpstateBaseTest {
public:
Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 9344368..934646d 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -165,7 +165,7 @@
#endif // !VENDORSERVICEMANAGER
// implicitly unlinked when the binder is removed
- if (OK != binder->linkToDeath(this)) {
+ if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index 11d43a6..4b12fc6 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -23,11 +23,12 @@
#include "Access.h"
#include "ServiceManager.h"
-using ::android::sp;
-using ::android::ProcessState;
-using ::android::IPCThreadState;
-using ::android::ServiceManager;
using ::android::Access;
+using ::android::IPCThreadState;
+using ::android::ProcessState;
+using ::android::ServiceManager;
+using ::android::os::IServiceManager;
+using ::android::sp;
int main(int argc, char** argv) {
if (argc > 2) {
@@ -41,6 +42,10 @@
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
+ if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
+ LOG(ERROR) << "Could not self register servicemanager";
+ }
+
IPCThreadState::self()->setTheContextObject(manager);
ps->becomeContextManager(nullptr, nullptr);
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index c056c97..1822e4a 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -60,14 +60,14 @@
* in StructLayout_test should be made.
*/
struct InputMessage {
- enum {
- TYPE_KEY = 1,
- TYPE_MOTION = 2,
- TYPE_FINISHED = 3,
+ enum class Type : uint32_t {
+ KEY,
+ MOTION,
+ FINISHED,
};
struct Header {
- uint32_t type;
+ Type type; // 4 bytes
// We don't need this field in order to align the body below but we
// leave it here because InputMessage::size() and other functions
// compute the size of this structure as sizeof(Header) + sizeof(Body).
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 643a956..7ee4882 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -73,6 +73,7 @@
// or dessert updates. Instead, apex users should use libbinder_ndk.
apex_available: [
"//apex_available:platform",
+ "com.android.vndk.current",
// TODO(b/139016109) remove these three
"com.android.media.swcodec",
"test_com.android.media.swcodec",
@@ -164,3 +165,16 @@
],
path: "aidl",
}
+
+aidl_interface {
+ name: "libbinder_aidl_test_stub",
+ local_include_dir: "aidl",
+ srcs: [":libbinder_aidl"],
+ visibility: [":__subpackages__"],
+ vendor_available: true,
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
+}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 323e079..7219b47 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -505,7 +505,7 @@
}
}
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
#else
constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 6971c72..3f47f3b 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -188,6 +188,30 @@
return count;
}
+// Queries the driver for the current strong reference count of the node
+// that the handle points to. Can only be used by the servicemanager.
+//
+// Returns -1 in case of failure, otherwise the strong reference count.
+ssize_t ProcessState::getStrongRefCountForNodeByHandle(int32_t handle) {
+ binder_node_info_for_ref info;
+ memset(&info, 0, sizeof(binder_node_info_for_ref));
+
+ info.handle = handle;
+
+ status_t result = ioctl(mDriverFD, BINDER_GET_NODE_INFO_FOR_REF, &info);
+
+ if (result != OK) {
+ static bool logged = false;
+ if (!logged) {
+ ALOGW("Kernel does not support BINDER_GET_NODE_INFO_FOR_REF.");
+ logged = true;
+ }
+ return -1;
+ }
+
+ return info.strong_count;
+}
+
void ProcessState::setCallRestriction(CallRestriction restriction) {
LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull() != nullptr,
"Call restrictions must be set before the threadpool is started.");
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 60c2cce..471b63f 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -31,22 +31,22 @@
* Must update values in IServiceManager.h
*/
/* Allows services to dump sections according to priorities. */
- const int DUMP_FLAG_PRIORITY_CRITICAL = 1; // 1 << 0
- const int DUMP_FLAG_PRIORITY_HIGH = 2; // 1 << 1
- const int DUMP_FLAG_PRIORITY_NORMAL = 4; // 1 << 2
+ const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
+ const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
+ const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
/**
* Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
* same priority as NORMAL priority but the services are not called with dump priority
* arguments.
*/
- const int DUMP_FLAG_PRIORITY_DEFAULT = 8; // 1 << 3
+ const int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
const int DUMP_FLAG_PRIORITY_ALL = 15;
// DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
// | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
/* Allows services to dump sections in protobuf format. */
- const int DUMP_FLAG_PROTO = 16; // 1 << 4
+ const int DUMP_FLAG_PROTO = 1 << 4;
/**
* Retrieve an existing service called @a name from the
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index f7c38f4..e57ff1c 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -69,6 +69,14 @@
ssize_t getKernelReferences(size_t count, uintptr_t* buf);
+ // Only usable by the context manager.
+ // This refcount includes:
+ // 1. Strong references to the node by this and other processes
+ // 2. Temporary strong references held by the kernel during a
+ // transaction on the node.
+ // It does NOT include local strong references to the node
+ ssize_t getStrongRefCountForNodeByHandle(int32_t handle);
+
enum class CallRestriction {
// all calls okay
NONE,
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index 2894482..b2f51d3 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -81,7 +81,7 @@
VINTF = 0b111111,
};
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
static constexpr Level kLocalStability = Level::VENDOR;
#else
static constexpr Level kLocalStability = Level::SYSTEM;
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index e1a8cfd..2a4ded8 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -30,7 +30,8 @@
FLAG_PRIVATE_VENDOR = 0x10000000,
};
-#if (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
+#if defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || \
+ (defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__))
enum {
FLAG_PRIVATE_LOCAL = FLAG_PRIVATE_VENDOR,
@@ -45,7 +46,8 @@
AIBinder_markVendorStability(binder);
}
-#else // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#else // defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) &&
+ // !defined(__ANDROID_APEX__))
enum {
FLAG_PRIVATE_LOCAL = 0,
@@ -60,7 +62,8 @@
AIBinder_markSystemStability(binder);
}
-#endif // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#endif // defined(__ANDROID_APEX_COM_ANDROID_VNDK_CURRENT__) || (defined(__ANDROID_VNDK__) &&
+ // !defined(__ANDROID_APEX__))
/**
* This interface has system<->vendor stability
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index 1c5dba3..ebd08b2 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -77,6 +77,7 @@
static_libs: [
"IBinderVendorDoubleLoadTest-cpp",
"IBinderVendorDoubleLoadTest-ndk_platform",
+ "libbinder_aidl_test_stub-ndk_platform",
],
shared_libs: [
"libbase",
diff --git a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
index f72dc36..d3ccdc2 100644
--- a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
+++ b/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
@@ -16,6 +16,7 @@
#include <BnBinderVendorDoubleLoadTest.h>
#include <aidl/BnBinderVendorDoubleLoadTest.h>
+#include <aidl/android/os/IServiceManager.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
@@ -109,6 +110,24 @@
}
}
+TEST(DoubleBinder, CallIntoSystemStabilityNdk) {
+ // picking an arbitrary system service
+ SpAIBinder binder = SpAIBinder(AServiceManager_checkService("manager"));
+ ASSERT_NE(nullptr, binder.get());
+
+ // can make stable transaction to system server
+ EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
+
+ using aidl::android::os::IServiceManager;
+ std::shared_ptr<IServiceManager> manager = IServiceManager::fromBinder(binder);
+ ASSERT_NE(nullptr, manager.get());
+
+ std::vector<std::string> services;
+ ASSERT_EQ(
+ STATUS_BAD_TYPE,
+ manager->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL, &services).getStatus());
+}
+
void initDrivers() {
// Explicitly instantiated with the same driver that system would use.
// __ANDROID_VNDK__ right now uses /dev/vndbinder by default.
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 5fb3f0b..c1d92a2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -43,6 +43,27 @@
}
}
+void BufferQueue::ProxyConsumerListener::onFrameDequeued(const uint64_t bufferId) {
+ sp<ConsumerListener> listener(mConsumerListener.promote());
+ if (listener != nullptr) {
+ listener->onFrameDequeued(bufferId);
+ }
+}
+
+void BufferQueue::ProxyConsumerListener::onFrameCancelled(const uint64_t bufferId) {
+ sp<ConsumerListener> listener(mConsumerListener.promote());
+ if (listener != nullptr) {
+ listener->onFrameCancelled(bufferId);
+ }
+}
+
+void BufferQueue::ProxyConsumerListener::onFrameDetached(const uint64_t bufferId) {
+ sp<ConsumerListener> listener(mConsumerListener.promote());
+ if (listener != nullptr) {
+ listener->onFrameDetached(bufferId);
+ }
+}
+
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
const BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 5674674..09c74de 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -580,6 +580,11 @@
}
addAndGetFrameTimestamps(nullptr, outTimestamps);
+ { // Autolock scope
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
+ mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
+ }
+
return returnFlags;
}
@@ -621,13 +626,16 @@
return BAD_VALUE;
}
+ listener = mCore->mConsumerListener;
+ if (listener != nullptr) {
+ listener->onFrameDetached(mSlots[slot].mGraphicBuffer->getId());
+ }
mSlots[slot].mBufferState.detachProducer();
mCore->mActiveBuffers.erase(slot);
mCore->mFreeSlots.insert(slot);
mCore->clearBufferSlotLocked(slot);
mCore->mDequeueCondition.notify_all();
VALIDATE_CONSISTENCY();
- listener = mCore->mConsumerListener;
}
if (listener != nullptr) {
@@ -1083,6 +1091,9 @@
mCore->mFreeBuffers.push_back(slot);
}
+ if (mCore->mConsumerListener != nullptr) {
+ mCore->mConsumerListener->onFrameCancelled(mSlots[slot].mGraphicBuffer->getId());
+ }
mSlots[slot].mFence = fence;
mCore->mDequeueCondition.notify_all();
VALIDATE_CONSISTENCY();
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index abd9921..9f91d9d 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -101,6 +101,48 @@
mSlots[slotIndex].mFrameNumber = 0;
}
+void ConsumerBase::onFrameDequeued(const uint64_t bufferId) {
+ CB_LOGV("onFrameDequeued");
+
+ sp<FrameAvailableListener> listener;
+ {
+ Mutex::Autolock lock(mFrameAvailableMutex);
+ listener = mFrameAvailableListener.promote();
+ }
+
+ if (listener != nullptr) {
+ listener->onFrameDequeued(bufferId);
+ }
+}
+
+void ConsumerBase::onFrameCancelled(const uint64_t bufferId) {
+ CB_LOGV("onFrameCancelled");
+
+ sp<FrameAvailableListener> listener;
+ {
+ Mutex::Autolock lock(mFrameAvailableMutex);
+ listener = mFrameAvailableListener.promote();
+ }
+
+ if (listener != nullptr) {
+ listener->onFrameCancelled(bufferId);
+ }
+}
+
+void ConsumerBase::onFrameDetached(const uint64_t bufferId) {
+ CB_LOGV("onFrameDetached");
+
+ sp<FrameAvailableListener> listener;
+ {
+ Mutex::Autolock lock(mFrameAvailableMutex);
+ listener = mFrameAvailableListener.promote();
+ }
+
+ if (listener != nullptr) {
+ listener->onFrameDetached(bufferId);
+ }
+}
+
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index 85ac304..48cb4b9 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -28,7 +28,10 @@
ON_FRAME_REPLACED,
ON_BUFFERS_RELEASED,
ON_SIDEBAND_STREAM_CHANGED,
- LAST = ON_SIDEBAND_STREAM_CHANGED,
+ ON_FRAME_DEQUEUED,
+ ON_FRAME_CANCELLED,
+ ON_FRAME_DETACHED,
+ LAST = ON_FRAME_DETACHED,
};
} // Anonymous namespace
@@ -44,6 +47,21 @@
callRemoteAsync<decltype(&IConsumerListener::onDisconnect)>(Tag::ON_DISCONNECT);
}
+ void onFrameDequeued(const uint64_t bufferId) override {
+ callRemoteAsync<decltype(&IConsumerListener::onFrameDequeued)>(Tag::ON_FRAME_DEQUEUED,
+ bufferId);
+ }
+
+ void onFrameDetached(const uint64_t bufferId) override {
+ callRemoteAsync<decltype(&IConsumerListener::onFrameDetached)>(Tag::ON_FRAME_DETACHED,
+ bufferId);
+ }
+
+ void onFrameCancelled(const uint64_t bufferId) override {
+ callRemoteAsync<decltype(&IConsumerListener::onFrameCancelled)>(Tag::ON_FRAME_CANCELLED,
+ bufferId);
+ }
+
void onFrameAvailable(const BufferItem& item) override {
callRemoteAsync<decltype(&IConsumerListener::onFrameAvailable)>(Tag::ON_FRAME_AVAILABLE,
item);
@@ -93,6 +111,12 @@
return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased);
case Tag::ON_SIDEBAND_STREAM_CHANGED:
return callLocalAsync(data, reply, &IConsumerListener::onSidebandStreamChanged);
+ case Tag::ON_FRAME_DEQUEUED:
+ return callLocalAsync(data, reply, &IConsumerListener::onFrameDequeued);
+ case Tag::ON_FRAME_CANCELLED:
+ return callLocalAsync(data, reply, &IConsumerListener::onFrameCancelled);
+ case Tag::ON_FRAME_DETACHED:
+ return callLocalAsync(data, reply, &IConsumerListener::onFrameDetached);
}
}
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index acda600..e5e25aa 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -48,6 +48,7 @@
} else {
err = output->writeBool(false);
}
+ err = output->writeUint32(transformHint);
return err;
}
@@ -72,7 +73,8 @@
return err;
}
}
- return NO_ERROR;
+ err = input->readUint32(&transformHint);
+ return err;
}
status_t TransactionStats::writeToParcel(Parcel* output) const {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7b256f5..e9079ef 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -222,7 +222,8 @@
for (const auto& surfaceStats : transactionStats.surfaceStats) {
surfaceControlStats.emplace_back(surfaceControls[surfaceStats.surfaceControl],
surfaceStats.acquireTime,
- surfaceStats.previousReleaseFence);
+ surfaceStats.previousReleaseFence,
+ surfaceStats.transformHint);
}
callbackFunction(transactionStats.latchTime, transactionStats.presentFence,
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index da95274..91f80d2 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -63,6 +63,9 @@
void onFrameReplaced(const BufferItem& item) override;
void onBuffersReleased() override;
void onSidebandStreamChanged() override;
+ void onFrameDequeued(const uint64_t bufferId) override;
+ void onFrameCancelled(const uint64_t bufferId) override;
+ void onFrameDetached(const uint64_t bufferID) override;
void addAndGetFrameTimestamps(
const NewFrameEventsEntry* newTimestamps,
FrameEventHistoryDelta* outDelta) override;
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index 366ced3..8ff0cd0 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -45,6 +45,9 @@
// See IConsumerListener::onFrame{Available,Replaced}
virtual void onFrameAvailable(const BufferItem& item) = 0;
virtual void onFrameReplaced(const BufferItem& /* item */) {}
+ virtual void onFrameDequeued(const uint64_t){};
+ virtual void onFrameCancelled(const uint64_t){};
+ virtual void onFrameDetached(const uint64_t){};
};
~ConsumerBase() override;
@@ -141,6 +144,9 @@
// classes if they want the notification.
virtual void onFrameAvailable(const BufferItem& item) override;
virtual void onFrameReplaced(const BufferItem& item) override;
+ virtual void onFrameDequeued(const uint64_t bufferId) override;
+ virtual void onFrameCancelled(const uint64_t bufferId) override;
+ virtual void onFrameDetached(const uint64_t bufferId) override;
virtual void onBuffersReleased() override;
virtual void onSidebandStreamChanged() override;
diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h
index c082882..046f6e1 100644
--- a/libs/gui/include/gui/IConsumerListener.h
+++ b/libs/gui/include/gui/IConsumerListener.h
@@ -43,6 +43,17 @@
// onDisconnect is called when a producer disconnects from the BufferQueue.
virtual void onDisconnect() {} /* Asynchronous */
+ // onFrameDequeued is called when a call to the BufferQueueProducer::dequeueBuffer successfully
+ // returns a slot from the BufferQueue.
+ virtual void onFrameDequeued(const uint64_t) {}
+
+ // onFrameCancelled is called when the client calls cancelBuffer, thereby releasing the slot
+ // back to the BufferQueue.
+ virtual void onFrameCancelled(const uint64_t) {}
+
+ // onFrameDetached is called after a successful detachBuffer() call while in asynchronous mode.
+ virtual void onFrameDetached(const uint64_t) {}
+
// onFrameAvailable is called from queueBuffer each time an additional frame becomes available
// for consumption. This means that frames that are queued while in asynchronous mode only
// trigger the callback if no previous frames are pending. Frames queued while in synchronous
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index 178ca2d..9c15225 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -41,12 +41,17 @@
status_t readFromParcel(const Parcel* input) override;
SurfaceStats() = default;
- SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence)
- : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {}
+ SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence,
+ uint32_t hint)
+ : surfaceControl(sc),
+ acquireTime(time),
+ previousReleaseFence(prevReleaseFence),
+ transformHint(hint) {}
sp<IBinder> surfaceControl;
nsecs_t acquireTime = -1;
sp<Fence> previousReleaseFence;
+ uint32_t transformHint = 0;
};
class TransactionStats : public Parcelable {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 6676be4..08f4e9e 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -58,12 +58,16 @@
struct SurfaceControlStats {
SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t time,
- const sp<Fence>& prevReleaseFence)
- : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {}
+ const sp<Fence>& prevReleaseFence, uint32_t hint)
+ : surfaceControl(sc),
+ acquireTime(time),
+ previousReleaseFence(prevReleaseFence),
+ transformHint(hint) {}
sp<SurfaceControl> surfaceControl;
nsecs_t acquireTime = -1;
sp<Fence> previousReleaseFence;
+ uint32_t transformHint = 0;
};
using TransactionCompletedCallbackTakesContext =
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 366c93c..c4f7fe0 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -93,13 +93,12 @@
bool InputMessage::isValid(size_t actualSize) const {
if (size() == actualSize) {
switch (header.type) {
- case TYPE_KEY:
- return true;
- case TYPE_MOTION:
- return body.motion.pointerCount > 0
- && body.motion.pointerCount <= MAX_POINTERS;
- case TYPE_FINISHED:
- return true;
+ case Type::KEY:
+ return true;
+ case Type::MOTION:
+ return body.motion.pointerCount > 0 && body.motion.pointerCount <= MAX_POINTERS;
+ case Type::FINISHED:
+ return true;
}
}
return false;
@@ -107,12 +106,12 @@
size_t InputMessage::size() const {
switch (header.type) {
- case TYPE_KEY:
- return sizeof(Header) + body.key.size();
- case TYPE_MOTION:
- return sizeof(Header) + body.motion.size();
- case TYPE_FINISHED:
- return sizeof(Header) + body.finished.size();
+ case Type::KEY:
+ return sizeof(Header) + body.key.size();
+ case Type::MOTION:
+ return sizeof(Header) + body.motion.size();
+ case Type::FINISHED:
+ return sizeof(Header) + body.finished.size();
}
return sizeof(Header);
}
@@ -129,7 +128,7 @@
// Write the body
switch(header.type) {
- case InputMessage::TYPE_KEY: {
+ case InputMessage::Type::KEY: {
// uint32_t seq
msg->body.key.seq = body.key.seq;
// nsecs_t eventTime
@@ -156,7 +155,7 @@
msg->body.key.downTime = body.key.downTime;
break;
}
- case InputMessage::TYPE_MOTION: {
+ case InputMessage::Type::MOTION: {
// uint32_t seq
msg->body.motion.seq = body.motion.seq;
// nsecs_t eventTime
@@ -212,7 +211,7 @@
}
break;
}
- case InputMessage::TYPE_FINISHED: {
+ case InputMessage::Type::FINISHED: {
msg->body.finished.seq = body.finished.seq;
msg->body.finished.handled = body.finished.handled;
break;
@@ -457,7 +456,7 @@
}
InputMessage msg;
- msg.header.type = InputMessage::TYPE_KEY;
+ msg.header.type = InputMessage::Type::KEY;
msg.body.key.seq = seq;
msg.body.key.deviceId = deviceId;
msg.body.key.source = source;
@@ -511,7 +510,7 @@
}
InputMessage msg;
- msg.header.type = InputMessage::TYPE_MOTION;
+ msg.header.type = InputMessage::Type::MOTION;
msg.body.motion.seq = seq;
msg.body.motion.deviceId = deviceId;
msg.body.motion.source = source;
@@ -553,7 +552,7 @@
*outHandled = false;
return result;
}
- if (msg.header.type != InputMessage::TYPE_FINISHED) {
+ if (msg.header.type != InputMessage::Type::FINISHED) {
ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
mChannel->getName().c_str(), msg.header.type);
return UNKNOWN_ERROR;
@@ -614,59 +613,59 @@
}
switch (mMsg.header.type) {
- case InputMessage::TYPE_KEY: {
- KeyEvent* keyEvent = factory->createKeyEvent();
- if (!keyEvent) return NO_MEMORY;
+ case InputMessage::Type::KEY: {
+ KeyEvent* keyEvent = factory->createKeyEvent();
+ if (!keyEvent) return NO_MEMORY;
- initializeKeyEvent(keyEvent, &mMsg);
- *outSeq = mMsg.body.key.seq;
- *outEvent = keyEvent;
+ initializeKeyEvent(keyEvent, &mMsg);
+ *outSeq = mMsg.body.key.seq;
+ *outEvent = keyEvent;
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
mChannel->getName().c_str(), *outSeq);
#endif
break;
- }
+ }
- case InputMessage::TYPE_MOTION: {
- ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
- if (batchIndex >= 0) {
- Batch& batch = mBatches.editItemAt(batchIndex);
- if (canAddSample(batch, &mMsg)) {
- batch.samples.push(mMsg);
+ case InputMessage::Type::MOTION: {
+ ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
+ if (batchIndex >= 0) {
+ Batch& batch = mBatches.editItemAt(batchIndex);
+ if (canAddSample(batch, &mMsg)) {
+ batch.samples.push(mMsg);
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ appended to batch event",
mChannel->getName().c_str());
#endif
break;
- } else if (isPointerEvent(mMsg.body.motion.source) &&
- mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
- // No need to process events that we are going to cancel anyways
- const size_t count = batch.samples.size();
- for (size_t i = 0; i < count; i++) {
- const InputMessage& msg = batch.samples.itemAt(i);
- sendFinishedSignal(msg.body.motion.seq, false);
- }
- batch.samples.removeItemsAt(0, count);
- mBatches.removeAt(batchIndex);
- } else {
- // We cannot append to the batch in progress, so we need to consume
- // the previous batch right now and defer the new message until later.
- mMsgDeferred = true;
- status_t result = consumeSamples(factory,
- batch, batch.samples.size(), outSeq, outEvent);
- mBatches.removeAt(batchIndex);
- if (result) {
- return result;
- }
+ } else if (isPointerEvent(mMsg.body.motion.source) &&
+ mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
+ // No need to process events that we are going to cancel anyways
+ const size_t count = batch.samples.size();
+ for (size_t i = 0; i < count; i++) {
+ const InputMessage& msg = batch.samples.itemAt(i);
+ sendFinishedSignal(msg.body.motion.seq, false);
+ }
+ batch.samples.removeItemsAt(0, count);
+ mBatches.removeAt(batchIndex);
+ } else {
+ // We cannot append to the batch in progress, so we need to consume
+ // the previous batch right now and defer the new message until later.
+ mMsgDeferred = true;
+ status_t result = consumeSamples(factory, batch, batch.samples.size(),
+ outSeq, outEvent);
+ mBatches.removeAt(batchIndex);
+ if (result) {
+ return result;
+ }
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed batch event and "
"deferred current event, seq=%u",
mChannel->getName().c_str(), *outSeq);
#endif
break;
+ }
}
- }
// Start a new batch if needed.
if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
@@ -694,7 +693,7 @@
mChannel->getName().c_str(), *outSeq);
#endif
break;
- }
+ }
default:
ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
@@ -1074,7 +1073,7 @@
status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
InputMessage msg;
- msg.header.type = InputMessage::TYPE_FINISHED;
+ msg.header.type = InputMessage::Type::FINISHED;
msg.body.finished.seq = seq;
msg.body.finished.handled = handled;
return mChannel->sendMessage(&msg);
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
index af74edd..7c331e1 100644
--- a/libs/input/tests/InputChannel_test.cpp
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -86,7 +86,7 @@
// Server->Client communication
InputMessage serverMsg;
memset(&serverMsg, 0, sizeof(InputMessage));
- serverMsg.header.type = InputMessage::TYPE_KEY;
+ serverMsg.header.type = InputMessage::Type::KEY;
serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
<< "server channel should be able to send message to client channel";
@@ -102,7 +102,7 @@
// Client->Server communication
InputMessage clientReply;
memset(&clientReply, 0, sizeof(InputMessage));
- clientReply.header.type = InputMessage::TYPE_FINISHED;
+ clientReply.header.type = InputMessage::Type::FINISHED;
clientReply.body.finished.seq = 0x11223344;
clientReply.body.finished.handled = true;
EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
@@ -161,7 +161,7 @@
serverChannel.clear(); // close server channel
InputMessage msg;
- msg.header.type = InputMessage::TYPE_KEY;
+ msg.header.type = InputMessage::Type::KEY;
EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
<< "sendMessage should have returned DEAD_OBJECT";
}
@@ -180,7 +180,7 @@
};
InputMessage serverMsg = {}, clientMsg;
- serverMsg.header.type = InputMessage::TYPE_MOTION;
+ serverMsg.header.type = InputMessage::Type::MOTION;
serverMsg.body.motion.seq = 1;
serverMsg.body.motion.pointerCount = 1;
diff --git a/libs/renderengine/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp
index 166c267..0fdf093 100644
--- a/libs/renderengine/RenderEngine.cpp
+++ b/libs/renderengine/RenderEngine.cpp
@@ -24,23 +24,22 @@
namespace android {
namespace renderengine {
-std::unique_ptr<impl::RenderEngine> RenderEngine::create(int hwcFormat, uint32_t featureFlags,
- uint32_t imageCacheSize) {
+std::unique_ptr<impl::RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
char prop[PROPERTY_VALUE_MAX];
property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "gles");
if (strcmp(prop, "gles") == 0) {
ALOGD("RenderEngine GLES Backend");
- return renderengine::gl::GLESRenderEngine::create(hwcFormat, featureFlags, imageCacheSize);
+ return renderengine::gl::GLESRenderEngine::create(args);
}
ALOGE("UNKNOWN BackendType: %s, create GLES RenderEngine.", prop);
- return renderengine::gl::GLESRenderEngine::create(hwcFormat, featureFlags, imageCacheSize);
+ return renderengine::gl::GLESRenderEngine::create(args);
}
RenderEngine::~RenderEngine() = default;
namespace impl {
-RenderEngine::RenderEngine(uint32_t featureFlags) : mFeatureFlags(featureFlags) {}
+RenderEngine::RenderEngine(const RenderEngineCreationArgs& args) : mArgs(args) {}
RenderEngine::~RenderEngine() = default;
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index b8cf0ea..15d025b 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -227,8 +227,7 @@
return err;
}
-std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(int hwcFormat, uint32_t featureFlags,
- uint32_t imageCacheSize) {
+std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) {
// initialize EGL for the default display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!eglInitialize(display, nullptr, nullptr)) {
@@ -243,14 +242,13 @@
// supported.
EGLConfig config = EGL_NO_CONFIG;
if (!extensions.hasNoConfigContext()) {
- config = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
+ config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
}
- bool useContextPriority = extensions.hasContextPriority() &&
- (featureFlags & RenderEngine::USE_HIGH_PRIORITY_CONTEXT);
+ bool useContextPriority =
+ extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH;
EGLContext protectedContext = EGL_NO_CONTEXT;
- if ((featureFlags & RenderEngine::ENABLE_PROTECTED_CONTEXT) &&
- extensions.hasProtectedContent()) {
+ if (args.enableProtectedContext && extensions.hasProtectedContent()) {
protectedContext = createEglContext(display, config, nullptr, useContextPriority,
Protection::PROTECTED);
ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
@@ -264,7 +262,8 @@
EGLSurface dummy = EGL_NO_SURFACE;
if (!extensions.hasSurfacelessContext()) {
- dummy = createDummyEglPbufferSurface(display, config, hwcFormat, Protection::UNPROTECTED);
+ dummy = createDummyEglPbufferSurface(display, config, args.pixelFormat,
+ Protection::UNPROTECTED);
LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
}
EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
@@ -274,8 +273,8 @@
EGLSurface protectedDummy = EGL_NO_SURFACE;
if (protectedContext != EGL_NO_CONTEXT && !extensions.hasSurfacelessContext()) {
- protectedDummy =
- createDummyEglPbufferSurface(display, config, hwcFormat, Protection::PROTECTED);
+ protectedDummy = createDummyEglPbufferSurface(display, config, args.pixelFormat,
+ Protection::PROTECTED);
ALOGE_IF(protectedDummy == EGL_NO_SURFACE, "can't create protected dummy pbuffer");
}
@@ -291,9 +290,8 @@
break;
case GLES_VERSION_2_0:
case GLES_VERSION_3_0:
- engine = std::make_unique<GLESRenderEngine>(featureFlags, display, config, ctxt, dummy,
- protectedContext, protectedDummy,
- imageCacheSize);
+ engine = std::make_unique<GLESRenderEngine>(args, display, config, ctxt, dummy,
+ protectedContext, protectedDummy);
break;
}
@@ -347,10 +345,10 @@
return config;
}
-GLESRenderEngine::GLESRenderEngine(uint32_t featureFlags, EGLDisplay display, EGLConfig config,
- EGLContext ctxt, EGLSurface dummy, EGLContext protectedContext,
- EGLSurface protectedDummy, uint32_t imageCacheSize)
- : renderengine::impl::RenderEngine(featureFlags),
+GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display,
+ EGLConfig config, EGLContext ctxt, EGLSurface dummy,
+ EGLContext protectedContext, EGLSurface protectedDummy)
+ : renderengine::impl::RenderEngine(args),
mEGLDisplay(display),
mEGLConfig(config),
mEGLContext(ctxt),
@@ -359,8 +357,8 @@
mProtectedDummySurface(protectedDummy),
mVpWidth(0),
mVpHeight(0),
- mFramebufferImageCacheSize(imageCacheSize),
- mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
+ mFramebufferImageCacheSize(args.imageCacheSize),
+ mUseColorManagement(args.useColorManagement) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
@@ -457,10 +455,9 @@
}
void GLESRenderEngine::primeCache() const {
- ProgramCache::getInstance().primeCache(
- mInProtectedContext ? mProtectedEGLContext : mEGLContext,
- mFeatureFlags & USE_COLOR_MANAGEMENT,
- mFeatureFlags & PRECACHE_TONE_MAPPER_SHADER_ONLY);
+ ProgramCache::getInstance().primeCache(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
+ mArgs.useColorManagement,
+ mArgs.precacheToneMapperShaderOnly);
}
base::unique_fd GLESRenderEngine::flush() {
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 501b044..397bc16 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -49,13 +49,11 @@
class GLESRenderEngine : public impl::RenderEngine {
public:
- static std::unique_ptr<GLESRenderEngine> create(int hwcFormat, uint32_t featureFlags,
- uint32_t imageCacheSize);
+ static std::unique_ptr<GLESRenderEngine> create(const RenderEngineCreationArgs& args);
- GLESRenderEngine(uint32_t featureFlags, // See RenderEngine::FeatureFlag
- EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy,
- EGLContext protectedContext, EGLSurface protectedDummy,
- uint32_t imageCacheSize);
+ GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLConfig config,
+ EGLContext ctxt, EGLSurface dummy, EGLContext protectedContext,
+ EGLSurface protectedDummy);
~GLESRenderEngine() override EXCLUDES(mRenderingMutex);
void primeCache() const override;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 9dcd510..4db5c57 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -48,6 +48,7 @@
class Image;
class Mesh;
class Texture;
+struct RenderEngineCreationArgs;
namespace impl {
class RenderEngine;
@@ -60,19 +61,13 @@
class RenderEngine {
public:
- enum FeatureFlag {
- USE_COLOR_MANAGEMENT = 1 << 0, // Device manages color
- USE_HIGH_PRIORITY_CONTEXT = 1 << 1, // Use high priority context
-
- // Create a protected context when if possible
- ENABLE_PROTECTED_CONTEXT = 1 << 2,
-
- // Only precache HDR to SDR tone-mapping shaders
- PRECACHE_TONE_MAPPER_SHADER_ONLY = 1 << 3,
+ enum class ContextPriority {
+ LOW = 1,
+ MEDIUM = 2,
+ HIGH = 3,
};
- static std::unique_ptr<impl::RenderEngine> create(int hwcFormat, uint32_t featureFlags,
- uint32_t imageCacheSize);
+ static std::unique_ptr<impl::RenderEngine> create(const RenderEngineCreationArgs& args);
virtual ~RenderEngine() = 0;
@@ -173,6 +168,76 @@
friend class BindNativeBufferAsFramebuffer;
};
+struct RenderEngineCreationArgs {
+ int pixelFormat;
+ uint32_t imageCacheSize;
+ bool useColorManagement;
+ bool enableProtectedContext;
+ bool precacheToneMapperShaderOnly;
+ RenderEngine::ContextPriority contextPriority;
+
+ struct Builder;
+
+private:
+ // must be created by Builder via constructor with full argument list
+ RenderEngineCreationArgs(
+ int _pixelFormat,
+ uint32_t _imageCacheSize,
+ bool _useColorManagement,
+ bool _enableProtectedContext,
+ bool _precacheToneMapperShaderOnly,
+ RenderEngine::ContextPriority _contextPriority)
+ : pixelFormat(_pixelFormat)
+ , imageCacheSize(_imageCacheSize)
+ , useColorManagement(_useColorManagement)
+ , enableProtectedContext(_enableProtectedContext)
+ , precacheToneMapperShaderOnly(_precacheToneMapperShaderOnly)
+ , contextPriority(_contextPriority) {}
+ RenderEngineCreationArgs() = delete;
+};
+
+struct RenderEngineCreationArgs::Builder {
+ Builder() {}
+
+ Builder& setPixelFormat(int pixelFormat) {
+ this->pixelFormat = pixelFormat;
+ return *this;
+ }
+ Builder& setImageCacheSize(uint32_t imageCacheSize) {
+ this->imageCacheSize = imageCacheSize;
+ return *this;
+ }
+ Builder& setUseColorManagerment(bool useColorManagement) {
+ this->useColorManagement = useColorManagement;
+ return *this;
+ }
+ Builder& setEnableProtectedContext(bool enableProtectedContext) {
+ this->enableProtectedContext = enableProtectedContext;
+ return *this;
+ }
+ Builder& setPrecacheToneMapperShaderOnly(bool precacheToneMapperShaderOnly) {
+ this->precacheToneMapperShaderOnly = precacheToneMapperShaderOnly;
+ return *this;
+ }
+ Builder& setContextPriority(RenderEngine::ContextPriority contextPriority) {
+ this->contextPriority = contextPriority;
+ return *this;
+ }
+ RenderEngineCreationArgs build() const {
+ return RenderEngineCreationArgs(pixelFormat, imageCacheSize, useColorManagement,
+ enableProtectedContext, precacheToneMapperShaderOnly, contextPriority);
+ }
+
+private:
+ // 1 means RGBA_8888
+ int pixelFormat = 1;
+ uint32_t imageCacheSize = 0;
+ bool useColorManagement = true;
+ bool enableProtectedContext = false;
+ bool precacheToneMapperShaderOnly = false;
+ RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
+};
+
class BindNativeBufferAsFramebuffer {
public:
BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer,
@@ -206,8 +271,8 @@
bool useWaitSync() const override;
protected:
- RenderEngine(uint32_t featureFlags);
- const uint32_t mFeatureFlags;
+ RenderEngine(const RenderEngineCreationArgs& args);
+ const RenderEngineCreationArgs mArgs;
};
} // namespace impl
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index f47c7fd..d01c740 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -31,9 +31,15 @@
struct RenderEngineTest : public ::testing::Test {
static void SetUpTestSuite() {
- sRE = renderengine::gl::GLESRenderEngine::create(static_cast<int32_t>(
- ui::PixelFormat::RGBA_8888),
- 0, 1);
+ sRE = renderengine::gl::GLESRenderEngine::create(
+ renderengine::RenderEngineCreationArgs::Builder()
+ .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
+ .setImageCacheSize(1)
+ .setUseColorManagerment(false)
+ .setEnableProtectedContext(false)
+ .setPrecacheToneMapperShaderOnly(false)
+ .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
+ .build());
}
static void TearDownTestSuite() {
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index cc9ccbc..9c600a8 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -140,6 +140,16 @@
status_t error =
mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle);
+ size_t bufSize;
+
+ // if stride has no meaning or is too large,
+ // approximate size with the input width instead
+ if (std::numeric_limits<size_t>::max() / height / (*stride) < static_cast<size_t>(bpp)) {
+ bufSize = static_cast<size_t>(width) * height * bpp;
+ } else {
+ bufSize = static_cast<size_t>((*stride)) * height * bpp;
+ }
+
if (error == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
@@ -150,7 +160,7 @@
rec.format = format;
rec.layerCount = layerCount;
rec.usage = usage;
- rec.size = static_cast<size_t>(height * (*stride) * bpp);
+ rec.size = bufSize;
rec.requestorName = std::move(requestorName);
list.add(*handle, rec);
diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h
index 25d4512..324d9e1 100644
--- a/libs/ui/include/ui/GraphicBufferAllocator.h
+++ b/libs/ui/include/ui/GraphicBufferAllocator.h
@@ -54,7 +54,7 @@
void dump(std::string& res) const;
static void dumpToSystemLog();
-private:
+protected:
struct alloc_rec_t {
uint32_t width;
uint32_t height;
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 0452f84..d2ad242 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,6 +29,26 @@
}
cc_test {
+ name: "GraphicBufferAllocator_test",
+ header_libs: [
+ "libdvr_headers",
+ "libnativewindow_headers",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ shared_libs: [
+ "liblog",
+ "libui",
+ ],
+ srcs: [
+ "GraphicBufferAllocator_test.cpp",
+ "mock/MockGrallocAllocator.cpp",
+ ],
+ cflags: ["-Wall", "-Werror"],
+}
+
+cc_test {
name: "GraphicBuffer_test",
header_libs: [
"libdvr_headers",
diff --git a/libs/ui/tests/GraphicBufferAllocator_test.cpp b/libs/ui/tests/GraphicBufferAllocator_test.cpp
new file mode 100644
index 0000000..4bbc549
--- /dev/null
+++ b/libs/ui/tests/GraphicBufferAllocator_test.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GraphicBufferAllocatorTest"
+
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+
+#include <gtest/gtest.h>
+
+#include "mock/MockGrallocAllocator.h"
+
+#include <algorithm>
+#include <limits>
+
+namespace android {
+
+namespace {
+
+constexpr uint32_t kTestWidth = 1024;
+constexpr uint32_t kTestHeight = 1;
+constexpr uint32_t kTestLayerCount = 1;
+constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+
+} // namespace
+
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+
+class TestableGraphicBufferAllocator : public GraphicBufferAllocator {
+public:
+ TestableGraphicBufferAllocator() {
+ mAllocator = std::make_unique<const mock::MockGrallocAllocator>();
+ }
+ void setUpAllocateExpectations(status_t err, uint32_t stride) {
+ std::cout << "Setting expected stride to " << stride << std::endl;
+ EXPECT_CALL(*(reinterpret_cast<const mock::MockGrallocAllocator*>(mAllocator.get())),
+ allocate)
+ .WillOnce(DoAll(SetArgPointee<6>(stride), Return(err)));
+ }
+ std::unique_ptr<const GrallocAllocator>& getAllocator() { return mAllocator; }
+};
+
+class GraphicBufferAllocatorTest : public testing::Test {
+public:
+ GraphicBufferAllocatorTest() : mAllocator() {}
+ const TestableGraphicBufferAllocator& getAllocator() { return mAllocator; }
+
+protected:
+ TestableGraphicBufferAllocator mAllocator;
+};
+
+TEST_F(GraphicBufferAllocatorTest, AllocateNoError) {
+ mAllocator.setUpAllocateExpectations(NO_ERROR, kTestWidth);
+ android::PixelFormat format = PIXEL_FORMAT_RGBA_8888;
+ uint32_t stride = 0;
+ buffer_handle_t handle;
+ status_t err = mAllocator.allocate(kTestWidth, kTestHeight, format, kTestLayerCount, kTestUsage,
+ &handle, &stride, 0, "GraphicBufferAllocatorTest");
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(kTestWidth, stride);
+}
+
+TEST_F(GraphicBufferAllocatorTest, AllocateBadStride) {
+ uint32_t height = std::numeric_limits<uint32_t>::max();
+ uint32_t bpp = 4;
+ android::PixelFormat format = PIXEL_FORMAT_RGBA_8888;
+
+ if (std::numeric_limits<size_t>::max() / height / bpp >= std::numeric_limits<uint32_t>::max()) {
+ std::cout << "stride cannot cause overflow" << std::endl;
+ GTEST_SUCCEED() << "stride cannot cause overflow";
+ return;
+ }
+ uint32_t width = std::numeric_limits<size_t>::max() / height / bpp;
+
+ uint32_t expectedStride = std::numeric_limits<uint32_t>::max();
+
+ mAllocator.setUpAllocateExpectations(NO_ERROR, expectedStride);
+ uint32_t stride = 0;
+ buffer_handle_t handle;
+ // an overflow would cause a crash
+ status_t err = mAllocator.allocate(width, height, format, kTestLayerCount, kTestUsage, &handle,
+ &stride, 0, "GraphicBufferAllocatorTest");
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(expectedStride, stride);
+}
+} // namespace android
diff --git a/libs/ui/tests/mock/MockGrallocAllocator.cpp b/libs/ui/tests/mock/MockGrallocAllocator.cpp
new file mode 100644
index 0000000..d71e25f
--- /dev/null
+++ b/libs/ui/tests/mock/MockGrallocAllocator.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MockGrallocAllocator.h"
+
+namespace android {
+
+namespace mock {
+
+MockGrallocAllocator::MockGrallocAllocator() = default;
+MockGrallocAllocator::~MockGrallocAllocator() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/libs/ui/tests/mock/MockGrallocAllocator.h b/libs/ui/tests/mock/MockGrallocAllocator.h
new file mode 100644
index 0000000..22c80a4
--- /dev/null
+++ b/libs/ui/tests/mock/MockGrallocAllocator.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include <ui/Gralloc.h>
+
+namespace android {
+
+class GraphicBuffer;
+
+namespace mock {
+
+class MockGrallocAllocator : public GrallocAllocator {
+public:
+ MockGrallocAllocator();
+ ~MockGrallocAllocator() override;
+
+ MOCK_METHOD(bool, isLoaded, (), (const, override));
+ MOCK_METHOD(std::string, dumpDebugInfo, (), (const, override));
+ MOCK_METHOD(status_t, allocate,
+ (uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles),
+ (const, override));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index ee8c344..d8cf8dd 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -245,7 +245,7 @@
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
: mPolicy(policy),
mPendingEvent(nullptr),
- mLastDropReason(DROP_REASON_NOT_DROPPED),
+ mLastDropReason(DropReason::NOT_DROPPED),
mAppSwitchSawKeyDown(false),
mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(nullptr),
@@ -374,11 +374,11 @@
// All events are eventually dequeued and processed this way, even if we intend to drop them.
ALOG_ASSERT(mPendingEvent != nullptr);
bool done = false;
- DropReason dropReason = DROP_REASON_NOT_DROPPED;
+ DropReason dropReason = DropReason::NOT_DROPPED;
if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
- dropReason = DROP_REASON_POLICY;
+ dropReason = DropReason::POLICY;
} else if (!mDispatchEnabled) {
- dropReason = DROP_REASON_DISABLED;
+ dropReason = DropReason::DISABLED;
}
if (mNextUnblockedEvent == mPendingEvent) {
@@ -390,14 +390,14 @@
ConfigurationChangedEntry* typedEntry =
static_cast<ConfigurationChangedEntry*>(mPendingEvent);
done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
+ dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
break;
}
case EventEntry::TYPE_DEVICE_RESET: {
DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
done = dispatchDeviceResetLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
+ dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
break;
}
@@ -407,15 +407,15 @@
if (isAppSwitchKeyEvent(typedEntry)) {
resetPendingAppSwitchLocked(true);
isAppSwitchDue = false;
- } else if (dropReason == DROP_REASON_NOT_DROPPED) {
- dropReason = DROP_REASON_APP_SWITCH;
+ } else if (dropReason == DropReason::NOT_DROPPED) {
+ dropReason = DropReason::APP_SWITCH;
}
}
- if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
+ if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
+ dropReason = DropReason::STALE;
}
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
+ if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
+ dropReason = DropReason::BLOCKED;
}
done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
break;
@@ -423,14 +423,14 @@
case EventEntry::TYPE_MOTION: {
MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
- dropReason = DROP_REASON_APP_SWITCH;
+ if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
+ dropReason = DropReason::APP_SWITCH;
}
- if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
+ if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
+ dropReason = DropReason::STALE;
}
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
+ if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
+ dropReason = DropReason::BLOCKED;
}
done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
break;
@@ -442,7 +442,7 @@
}
if (done) {
- if (dropReason != DROP_REASON_NOT_DROPPED) {
+ if (dropReason != DropReason::NOT_DROPPED) {
dropInboundEventLocked(mPendingEvent, dropReason);
}
mLastDropReason = dropReason;
@@ -594,35 +594,36 @@
void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
const char* reason;
switch (dropReason) {
- case DROP_REASON_POLICY:
+ case DropReason::POLICY:
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("Dropped event because policy consumed it.");
#endif
reason = "inbound event was dropped because the policy consumed it";
break;
- case DROP_REASON_DISABLED:
- if (mLastDropReason != DROP_REASON_DISABLED) {
+ case DropReason::DISABLED:
+ if (mLastDropReason != DropReason::DISABLED) {
ALOGI("Dropped event because input dispatch is disabled.");
}
reason = "inbound event was dropped because input dispatch is disabled";
break;
- case DROP_REASON_APP_SWITCH:
+ case DropReason::APP_SWITCH:
ALOGI("Dropped event because of pending overdue app switch.");
reason = "inbound event was dropped because of pending overdue app switch";
break;
- case DROP_REASON_BLOCKED:
+ case DropReason::BLOCKED:
ALOGI("Dropped event because the current application is not responding and the user "
"has started interacting with a different application.");
reason = "inbound event was dropped because the current application is not responding "
"and the user has started interacting with a different application";
break;
- case DROP_REASON_STALE:
+ case DropReason::STALE:
ALOGI("Dropped event because it is stale.");
reason = "inbound event was dropped because it is stale";
break;
- default:
- ALOG_ASSERT(false);
+ case DropReason::NOT_DROPPED: {
+ LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
return;
+ }
}
switch (entry->type) {
@@ -869,15 +870,15 @@
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
}
} else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
- if (*dropReason == DROP_REASON_NOT_DROPPED) {
- *dropReason = DROP_REASON_POLICY;
+ if (*dropReason == DropReason::NOT_DROPPED) {
+ *dropReason = DropReason::POLICY;
}
}
// Clean up if dropping the event.
- if (*dropReason != DROP_REASON_NOT_DROPPED) {
+ if (*dropReason != DropReason::NOT_DROPPED) {
setInjectionResult(entry,
- *dropReason == DROP_REASON_POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
+ *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
: INPUT_EVENT_INJECTION_FAILED);
mReporter->reportDroppedKey(entry->sequenceNum);
return true;
@@ -926,9 +927,9 @@
}
// Clean up if dropping the event.
- if (*dropReason != DROP_REASON_NOT_DROPPED) {
+ if (*dropReason != DropReason::NOT_DROPPED) {
setInjectionResult(entry,
- *dropReason == DROP_REASON_POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
+ *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
: INPUT_EVENT_INJECTION_FAILED);
return true;
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 1f906e4..9d22e2c 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -113,14 +113,13 @@
virtual status_t pilferPointers(const sp<IBinder>& token) override;
private:
-
- enum DropReason {
- DROP_REASON_NOT_DROPPED = 0,
- DROP_REASON_POLICY = 1,
- DROP_REASON_APP_SWITCH = 2,
- DROP_REASON_DISABLED = 3,
- DROP_REASON_BLOCKED = 4,
- DROP_REASON_STALE = 5,
+ enum class DropReason {
+ NOT_DROPPED,
+ POLICY,
+ APP_SWITCH,
+ DISABLED,
+ BLOCKED,
+ STALE,
};
sp<InputDispatcherPolicyInterface> mPolicy;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 34603b9..c80a2dc 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -668,7 +668,7 @@
naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
- naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
+ naturalPhysicalLeft = mViewport.deviceHeight - naturalPhysicalWidth;
naturalPhysicalTop = mViewport.physicalLeft;
naturalDeviceWidth = mViewport.deviceHeight;
naturalDeviceHeight = mViewport.deviceWidth;
@@ -689,7 +689,7 @@
naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
naturalPhysicalLeft = mViewport.physicalTop;
- naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
+ naturalPhysicalTop = mViewport.deviceWidth - naturalPhysicalHeight;
naturalDeviceWidth = mViewport.deviceHeight;
naturalDeviceHeight = mViewport.deviceWidth;
break;
@@ -2173,6 +2173,7 @@
// TODO: Adjust coverage coords?
float xTransformed = in.x, yTransformed = in.y;
mAffineTransform.applyTo(xTransformed, yTransformed);
+ rotateAndScale(xTransformed, yTransformed);
// Adjust X, Y, and coverage coords for surface orientation.
float x, y;
@@ -2180,8 +2181,8 @@
switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+ x = yTransformed + mYTranslate;
+ y = xTransformed + mXTranslate;
left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
@@ -2194,8 +2195,8 @@
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale;
- y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+ x = xTransformed + mXTranslate;
+ y = yTransformed + mYTranslate;
left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
@@ -2208,8 +2209,8 @@
}
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale;
- y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+ x = yTransformed + mYTranslate;
+ y = xTransformed + mXTranslate;
left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
@@ -2222,8 +2223,8 @@
}
break;
default:
- x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- y = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+ x = xTransformed + mXTranslate;
+ y = yTransformed + mYTranslate;
left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
@@ -3617,13 +3618,34 @@
abortTouches(when, 0 /* policyFlags*/);
}
+void TouchInputMapper::rotateAndScale(float& x, float& y) {
+ switch (mSurfaceOrientation) {
+ case DISPLAY_ORIENTATION_90:
+ x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
+ y = float(y - mRawPointerAxes.y.minValue) * mYScale;
+ break;
+ case DISPLAY_ORIENTATION_180:
+ x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
+ y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
+ break;
+ case DISPLAY_ORIENTATION_270:
+ x = float(x - mRawPointerAxes.x.minValue) * mXScale;
+ y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
+ break;
+ default:
+ x = float(x - mRawPointerAxes.x.minValue) * mXScale;
+ y = float(y - mRawPointerAxes.y.minValue) * mYScale;
+ break;
+ }
+}
+
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
- const float scaledX = x * mXScale;
- const float scaledY = y * mYScale;
+ float xTransformed = x, yTransformed = y;
+ rotateAndScale(xTransformed, yTransformed);
return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
- scaledX >= mSurfaceLeft && scaledX <= mSurfaceLeft + mSurfaceWidth &&
+ xTransformed >= mSurfaceLeft && xTransformed <= mSurfaceLeft + mSurfaceWidth &&
y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
- scaledY >= mSurfaceTop && scaledY <= mSurfaceTop + mSurfaceHeight;
+ yTransformed >= mSurfaceTop && yTransformed <= mSurfaceTop + mSurfaceHeight;
}
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 89c017d..4b1c0cb 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -758,6 +758,7 @@
static void assignPointerIds(const RawState* last, RawState* current);
const char* modeToString(DeviceMode deviceMode);
+ void rotateAndScale(float& x, float& y);
};
} // namespace android
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 31b1652..028fb6f 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -6614,20 +6614,41 @@
MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
- // Let surface be different from physical display.
- std::optional<DisplayViewport> internalViewport =
- mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
- internalViewport->logicalLeft = internalViewport->physicalTop + 20;
- internalViewport->logicalTop = internalViewport->physicalRight + 20;
- internalViewport->logicalRight = internalViewport->physicalRight - 20;
- internalViewport->logicalBottom = internalViewport->physicalBottom - 20;
- mFakePolicy->updateViewport(internalViewport.value());
-
prepareAxes(POSITION);
addMapperAndConfigure(mapper);
- int32_t rawX = 10;
- int32_t rawY = 10;
+ // Touch on left-top area should work.
+ int32_t rawX = DISPLAY_WIDTH / 2 - 1;
+ int32_t rawY = DISPLAY_HEIGHT / 2 - 1;
+ processPosition(mapper, rawX, rawY);
+ processSync(mapper);
+
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+
+ // Reset.
+ mapper->reset(ARBITRARY_TIME);
+
+ // Let logical display be different to physical display and rotate 90-degrees.
+ std::optional<DisplayViewport> internalViewport =
+ mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
+ internalViewport->orientation = DISPLAY_ORIENTATION_90;
+ internalViewport->logicalLeft = 0;
+ internalViewport->logicalTop = 0;
+ internalViewport->logicalRight = DISPLAY_HEIGHT;
+ internalViewport->logicalBottom = DISPLAY_WIDTH / 2;
+
+ internalViewport->physicalLeft = DISPLAY_HEIGHT;
+ internalViewport->physicalTop = DISPLAY_WIDTH / 2;
+ internalViewport->physicalRight = DISPLAY_HEIGHT;
+ internalViewport->physicalBottom = DISPLAY_WIDTH;
+
+ internalViewport->deviceWidth = DISPLAY_HEIGHT;
+ internalViewport->deviceHeight = DISPLAY_WIDTH;
+ mFakePolicy->updateViewport(internalViewport.value());
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+ // Display align to right-top after rotate 90-degrees, touch on left-top area should not work.
processPosition(mapper, rawX, rawY);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index a4f7797..8cc1831 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -372,11 +372,17 @@
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------
+void BufferQueueLayer::onFrameDequeued(const uint64_t bufferId) {
+ const int32_t layerID = getSequence();
+ mFlinger->mFrameTracer->traceTimestamp(layerID, bufferId, FrameTracer::UNSPECIFIED_FRAME_NUMBER,
+ systemTime(), FrameTracer::FrameEvent::DEQUEUE, 3000);
+}
+
void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
const int32_t layerID = getSequence();
mFlinger->mFrameTracer->traceNewLayer(layerID, getName().c_str());
mFlinger->mFrameTracer->traceTimestamp(layerID, item.mGraphicBuffer->getId(), item.mFrameNumber,
- systemTime(), FrameTracer::FrameEvent::POST);
+ systemTime(), FrameTracer::FrameEvent::QUEUE);
ATRACE_CALL();
// Add this buffer from our internal queue tracker
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index f3e8a19..95e0b10 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -93,6 +93,7 @@
void onFrameAvailable(const BufferItem& item) override;
void onFrameReplaced(const BufferItem& item) override;
void onSidebandStreamChanged() override;
+ void onFrameDequeued(const uint64_t bufferId) override;
// -----------------------------------------------------------------------
public:
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 6fe89c4..85d2253 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -103,12 +103,15 @@
}
}
-void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
- // TODO(marissaw): send the transform hint to buffer owner
- return;
+void BufferStateLayer::setTransformHint(uint32_t orientation) const {
+ mTransformHint = orientation;
}
void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
+ for (const auto& handle : mDrawingState.callbackHandles) {
+ handle->transformHint = mTransformHint;
+ }
+
mFlinger->getTransactionCompletedThread().finalizePendingCallbackHandles(
mDrawingState.callbackHandles);
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3dfe76c..289bb17 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -149,6 +149,8 @@
bool mReleasePreviousBuffer = false;
nsecs_t mCallbackHandleAcquireTime = -1;
+ mutable uint32_t mTransformHint = 0;
+
// TODO(marissaw): support sticky transform for LEGACY camera mode
class HwcSlotGenerator : public ClientCache::ErasedRecipient {
diff --git a/services/surfaceflinger/FrameTracer/FrameTracer.cpp b/services/surfaceflinger/FrameTracer/FrameTracer.cpp
index 006dbfe..3a0408e 100644
--- a/services/surfaceflinger/FrameTracer/FrameTracer.cpp
+++ b/services/surfaceflinger/FrameTracer/FrameTracer.cpp
@@ -133,7 +133,9 @@
packet->set_timestamp(timestamp);
auto* event = packet->set_graphics_frame_event()->set_buffer_event();
event->set_buffer_id(static_cast<uint32_t>(bufferID));
- event->set_frame_number(frameNumber);
+ if (frameNumber != UNSPECIFIED_FRAME_NUMBER) {
+ event->set_frame_number(frameNumber);
+ }
event->set_type(type);
if (mTraceTracker.find(layerID) != mTraceTracker.end() &&
diff --git a/services/surfaceflinger/FrameTracer/FrameTracer.h b/services/surfaceflinger/FrameTracer/FrameTracer.h
index d4dfab9..e91a750 100644
--- a/services/surfaceflinger/FrameTracer/FrameTracer.h
+++ b/services/surfaceflinger/FrameTracer/FrameTracer.h
@@ -33,6 +33,8 @@
virtual void OnStop(const StopArgs&) override{};
};
+ static const uint64_t UNSPECIFIED_FRAME_NUMBER = std::numeric_limits<uint64_t>::max();
+
using FrameEvent = perfetto::protos::pbzero::GraphicsFrameEvent;
~FrameTracer() = default;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ef9a598..057669b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -601,20 +601,19 @@
Mutex::Autolock _l(mStateLock);
// Get a RenderEngine for the given display / config (can't fail)
- int32_t renderEngineFeature = 0;
- renderEngineFeature |= (useColorManagement ?
- renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
- renderEngineFeature |= (useContextPriority ?
- renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
- renderEngineFeature |=
- (enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT
- : 0);
-
// TODO(b/77156734): We need to stop casting and use HAL types when possible.
// Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
- mCompositionEngine->setRenderEngine(
- renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
- renderEngineFeature, maxFrameBufferAcquiredBuffers));
+ mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
+ renderengine::RenderEngineCreationArgs::Builder()
+ .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
+ .setImageCacheSize(maxFrameBufferAcquiredBuffers)
+ .setUseColorManagerment(useColorManagement)
+ .setEnableProtectedContext(enable_protected_contents(false))
+ .setPrecacheToneMapperShaderOnly(false)
+ .setContextPriority(useContextPriority
+ ? renderengine::RenderEngine::ContextPriority::HIGH
+ : renderengine::RenderEngine::ContextPriority::MEDIUM)
+ .build()));
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
diff --git a/services/surfaceflinger/TimeStats/OWNERS b/services/surfaceflinger/TimeStats/OWNERS
index ac02d12..1441f91 100644
--- a/services/surfaceflinger/TimeStats/OWNERS
+++ b/services/surfaceflinger/TimeStats/OWNERS
@@ -1 +1,2 @@
-zzyiwei@google.com
\ No newline at end of file
+alecmouri@google.com
+zzyiwei@google.com
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index 92e59d7..8db03db 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -234,7 +234,8 @@
sp<IBinder> surfaceControl = handle->surfaceControl.promote();
if (surfaceControl) {
transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime,
- handle->previousReleaseFence);
+ handle->previousReleaseFence,
+ handle->transformHint);
}
return NO_ERROR;
}
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index a85ad1e..12ea8fe 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -44,6 +44,7 @@
sp<Fence> previousReleaseFence;
nsecs_t acquireTime = -1;
nsecs_t latchTime = -1;
+ uint32_t transformHint = 0;
};
class TransactionCompletedThread {
diff --git a/services/surfaceflinger/tests/utils/CallbackUtils.h b/services/surfaceflinger/tests/utils/CallbackUtils.h
index 51ae8c4..4e2b7c3 100644
--- a/services/surfaceflinger/tests/utils/CallbackUtils.h
+++ b/services/surfaceflinger/tests/utils/CallbackUtils.h
@@ -121,7 +121,8 @@
void verifySurfaceControlStats(const SurfaceControlStats& surfaceControlStats,
nsecs_t latchTime) const {
- const auto& [surfaceControl, acquireTime, previousReleaseFence] = surfaceControlStats;
+ const auto& [surfaceControl, acquireTime, previousReleaseFence, transformHint] =
+ surfaceControlStats;
ASSERT_EQ(acquireTime > 0, mBufferResult == ExpectedResult::Buffer::ACQUIRED)
<< "bad acquire time";
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 1578d9f..24039b1 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -1279,7 +1279,7 @@
return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
}
- // TODO how about extensions from implicitly enabled layers?
+ // TODO(b/143293104): expose extensions from implicitly enabled layers
return vulkan::driver::EnumerateInstanceExtensionProperties(
nullptr, pPropertyCount, pProperties);
}
@@ -1333,7 +1333,7 @@
return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
}
- // TODO how about extensions from implicitly enabled layers?
+ // TODO(b/143293104): expose extensions from implicitly enabled layers
const InstanceData& data = GetData(physicalDevice);
return data.dispatch.EnumerateDeviceExtensionProperties(
physicalDevice, nullptr, pPropertyCount, pProperties);
diff --git a/vulkan/libvulkan/debug_report.h b/vulkan/libvulkan/debug_report.h
index 3d8bd50..e5b1587 100644
--- a/vulkan/libvulkan/debug_report.h
+++ b/vulkan/libvulkan/debug_report.h
@@ -78,7 +78,7 @@
VkDebugReportCallbackEXT driver_handle;
};
- // TODO(jessehall): replace with std::shared_mutex when available in libc++
+ // TODO(b/143295577): use std::shared_mutex when available in libc++
mutable std::shared_timed_mutex rwmutex_;
Node head_;
};
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 2f6747d..a544bc5 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -151,12 +151,15 @@
Hal Hal::hal_;
void* LoadLibrary(const android_dlextinfo& dlextinfo,
- const std::string_view subname) {
+ const char* subname,
+ int subname_len) {
ATRACE_CALL();
- std::stringstream ss;
- ss << "vulkan." << subname << ".so";
- return android_dlopen_ext(ss.str().c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ const char kLibFormat[] = "vulkan.%*s.so";
+ char* name = static_cast<char*>(
+ alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
+ sprintf(name, kLibFormat, subname_len, subname);
+ return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
}
const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
@@ -176,9 +179,8 @@
char prop[PROPERTY_VALUE_MAX];
for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
int prop_len = property_get(key, prop, nullptr);
- if (prop_len > 0 && prop_len <= UINT_MAX) {
- std::string_view lib_name(prop, static_cast<unsigned int>(prop_len));
- so = LoadLibrary(dlextinfo, lib_name);
+ if (prop_len > 0) {
+ so = LoadLibrary(dlextinfo, prop, prop_len);
if (so)
break;
}
@@ -693,7 +695,7 @@
return nullptr;
}
- // TODO(jessehall): Right now we never shrink allocations; if the new
+ // TODO(b/143295633): Right now we never shrink allocations; if the new
// request is smaller than the existing chunk, we just continue using it.
// Right now the loader never reallocs, so this doesn't matter. If that
// changes, or if this code is copied into some other project, this should
@@ -1209,7 +1211,6 @@
}
data->driver_device = dev;
- data->driver_version = properties.driverVersion;
*pDevice = dev;
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index 61e1818..7edadea 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -98,7 +98,6 @@
VkDevice driver_device;
DeviceDriverTable driver;
- uint32_t driver_version;
};
bool Debuggable();
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index dd91739..2f33fee 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -24,7 +24,6 @@
#include <string.h>
#include <sys/prctl.h>
-#include <memory>
#include <mutex>
#include <string>
#include <vector>
@@ -39,13 +38,7 @@
#include <utils/Trace.h>
#include <ziparchive/zip_archive.h>
-// TODO(jessehall): The whole way we deal with extensions is pretty hokey, and
-// not a good long-term solution. Having a hard-coded enum of extensions is
-// bad, of course. Representing sets of extensions (requested, supported, etc.)
-// as a bitset isn't necessarily bad, if the mapping from extension to bit were
-// dynamic. Need to rethink this completely when there's a little more time.
-
-// TODO(jessehall): This file currently builds up global data structures as it
+// TODO(b/143296676): This file currently builds up global data structures as it
// loads, and never cleans them up. This means we're doing heap allocations
// without going through an app-provided allocator, but worse, we'll leak those
// allocations if the loader is unloaded.
@@ -102,7 +95,9 @@
bool EnumerateLayers(size_t library_idx,
std::vector<Layer>& instance_layers) const;
- void* GetGPA(const Layer& layer, const std::string_view gpa_name) const;
+ void* GetGPA(const Layer& layer,
+ const char* gpa_name,
+ size_t gpa_name_len) const;
const std::string GetFilename() { return filename_; }
@@ -225,10 +220,17 @@
}
// get layer properties
- auto properties = std::make_unique<VkLayerProperties[]>(num_instance_layers + num_device_layers);
+ VkLayerProperties* properties = static_cast<VkLayerProperties*>(alloca(
+ (num_instance_layers + num_device_layers) * sizeof(VkLayerProperties)));
+ result = enumerate_instance_layers(&num_instance_layers, properties);
+ if (result != VK_SUCCESS) {
+ ALOGE("vkEnumerateInstanceLayerProperties failed for library '%s': %d",
+ path_.c_str(), result);
+ return false;
+ }
if (num_device_layers > 0) {
result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers,
- properties.get() + num_instance_layers);
+ properties + num_instance_layers);
if (result != VK_SUCCESS) {
ALOGE(
"vkEnumerateDeviceLayerProperties failed for library '%s': %d",
@@ -313,11 +315,21 @@
return true;
}
-void* LayerLibrary::GetGPA(const Layer& layer, const std::string_view gpa_name) const {
- std::string layer_name { layer.properties.layerName };
- if (void* gpa = GetTrampoline((layer_name.append(gpa_name).c_str())))
- return gpa;
- return GetTrampoline((std::string {"vk"}.append(gpa_name)).c_str());
+void* LayerLibrary::GetGPA(const Layer& layer,
+ const char* gpa_name,
+ size_t gpa_name_len) const {
+ void* gpa;
+ size_t layer_name_len =
+ std::max(size_t{2}, strlen(layer.properties.layerName));
+ char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1));
+ strcpy(name, layer.properties.layerName);
+ strcpy(name + layer_name_len, gpa_name);
+ if (!(gpa = GetTrampoline(name))) {
+ strcpy(name, "vk");
+ strcpy(name + 2, gpa_name);
+ gpa = GetTrampoline(name);
+ }
+ return gpa;
}
// ----------------------------------------------------------------------------
@@ -452,9 +464,10 @@
}
void* GetLayerGetProcAddr(const Layer& layer,
- const std::string_view gpa_name) {
+ const char* gpa_name,
+ size_t gpa_name_len) {
const LayerLibrary& library = g_layer_libraries[layer.library_idx];
- return library.GetGPA(layer, gpa_name);
+ return library.GetGPA(layer, gpa_name, gpa_name_len);
}
} // anonymous namespace
@@ -537,13 +550,13 @@
PFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const {
return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>(
- GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr"))
+ GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr", 19))
: nullptr;
}
PFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const {
return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>(
- GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr"))
+ GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr", 17))
: nullptr;
}
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index bbf50a1..8f4667e 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -694,8 +694,8 @@
const InstanceData& instance_data = GetData(pdev);
- // TODO(jessehall): Fill out the set of supported formats. Longer term, add
- // a new gralloc method to query whether a (format, usage) pair is
+ // TODO(b/143296550): Fill out the set of supported formats. Longer term,
+ // add a new gralloc method to query whether a (format, usage) pair is
// supported, and check that for each gralloc format that corresponds to a
// Vulkan format. Shorter term, just add a few more formats to the ones
// hardcoded below.
@@ -704,8 +704,6 @@
{VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
{VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
{VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
- {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
- {VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
};
const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
uint32_t total_num_formats = kNumFormats;
@@ -953,7 +951,7 @@
strerror(-err), err);
}
- // TODO: Return something better than "whole window"
+ // TODO(b/143294545): Return something better than "whole window"
pRects[0].offset.x = 0;
pRects[0].offset.y = 0;
pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width),
@@ -1812,7 +1810,7 @@
return VK_ERROR_OUT_OF_DATE_KHR;
}
- // TODO(chrisforbes): Implement this function properly
+ // TODO(b/143296009): Implement this function properly
return result;
}