Merge "Use enum class for InputMessage type"
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..748f927 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");
}
@@ -1905,7 +1894,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 +1904,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 +1962,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 +2054,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 +2065,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 +2079,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 +2100,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 +2110,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 +2143,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 +2150,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 +2166,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 +2184,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 +2209,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 +2217,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 +2225,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 +2323,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 +2368,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 +2396,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 +2490,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 +2538,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 +3470,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/libs/binder/Android.bp b/libs/binder/Android.bp
index 643a956..2a140f4 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -164,3 +164,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/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/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/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/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/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";