Merge "dumpsys: add --thread option"
diff --git a/.clang-format b/.clang-format
index 03af56d..6725a1f 100644
--- a/.clang-format
+++ b/.clang-format
@@ -11,3 +11,4 @@
IndentWidth: 4
PenaltyBreakBeforeFirstCallParameter: 100000
SpacesBeforeTrailingComments: 1
+IncludeBlocks: Preserve
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index f494f6e..16ebf6f 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -5,6 +5,7 @@
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
cmds/idlcli/
+ cmds/servicemanager/
include/input/
libs/binder/fuzzer/
libs/binder/
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 8fd05fb..b8df99f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -793,6 +793,9 @@
if (module_metadata_version != 0) {
printf("Module Metadata version: %" PRId64 "\n", module_metadata_version);
}
+ printf("SDK extension versions [r=%s s=%s]\n",
+ android::base::GetProperty("build.version.extensions.r", "-").c_str(),
+ android::base::GetProperty("build.version.extensions.s", "-").c_str());
printf("Kernel: ");
DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
@@ -2174,14 +2177,13 @@
}
/*
- * mount debugfs for non-user builds which launch with S and unmount it
- * after invoking dumpstateBoard_* methods. This is to enable debug builds
- * to not have debugfs mounted during runtime. It will also ensure that
- * debugfs is only accessed by the dumpstate HAL.
+ * mount debugfs for non-user builds with ro.product.debugfs_restrictions.enabled
+ * set to true and unmount it after invoking dumpstateBoard_* methods.
+ * This is to enable debug builds to not have debugfs mounted during runtime.
+ * It will also ensure that debugfs is only accessed by the dumpstate HAL.
*/
- auto api_level = android::base::GetIntProperty("ro.product.first_api_level", 0);
- bool mount_debugfs = !PropertiesHelper::IsUserBuild() && api_level >= 31;
-
+ auto mount_debugfs =
+ android::base::GetBoolProperty("ro.product.debugfs_restrictions.enabled", false);
if (mount_debugfs) {
RunCommand("mount debugfs", {"mount", "-t", "debugfs", "debugfs", "/sys/kernel/debug"},
AS_ROOT_20);
@@ -2289,7 +2291,10 @@
}
if (mount_debugfs) {
- RunCommand("unmount debugfs", {"umount", "/sys/kernel/debug"}, AS_ROOT_20);
+ auto keep_debugfs_mounted =
+ android::base::GetProperty("persist.dbg.keep_debugfs_mounted", "");
+ if (keep_debugfs_mounted.empty())
+ RunCommand("unmount debugfs", {"umount", "/sys/kernel/debug"}, AS_ROOT_20);
}
auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 2c573e4..db508b5 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -1032,12 +1032,12 @@
ZipArchiveHandle handle_;
};
-// Generate a quick wifi report redirected to a file, open it and verify entry exist.
-TEST_F(ZippedBugReportStreamTest, StreamWifiReport) {
- std::string out_path = kTestDataPath + "out.zip";
+// Generate a quick LimitedOnly report redirected to a file, open it and verify entry exist.
+TEST_F(ZippedBugReportStreamTest, StreamLimitedOnlyReport) {
+ std::string out_path = kTestDataPath + "StreamLimitedOnlyReportOut.zip";
android::base::unique_fd out_fd;
CreateFd(out_path, &out_fd);
- ds_.options_->wifi_only = true;
+ ds_.options_->limited_only = true;
ds_.options_->stream_to_socket = true;
RedirectOutputToFd(out_fd);
@@ -1051,7 +1051,7 @@
ExtractToMemory(handle_, &entry, reinterpret_cast<uint8_t*>(bugreport_txt_name.data()),
entry.uncompressed_length);
EXPECT_THAT(bugreport_txt_name,
- testing::ContainsRegex("(bugreport-.+-wifi(-[[:digit:]]+){6}\\.txt)"));
+ testing::ContainsRegex("(bugreport-.+(-[[:digit:]]+){6}\\.txt)"));
VerifyEntry(handle_, bugreport_txt_name, &entry);
}
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index cf23f8a..d09d3e8 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -189,8 +189,8 @@
"liblog",
"libutils",
],
- static_libs: [
- "libapexd",
+ required: [
+ "apexd"
],
}
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 379cf92..83f01de 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -20,21 +20,19 @@
#include <sys/stat.h>
#include <sys/wait.h>
+#include <array>
#include <fstream>
#include <sstream>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <libdm/dm.h>
#include <selinux/android.h>
-#include <apex_file_repository.h>
-#include <apex_constants.h>
-#include <apexd.h>
-
#include "installd_constants.h"
#include "otapreopt_utils.h"
@@ -64,47 +62,23 @@
}
}
-static std::vector<apex::ApexFile> ActivateApexPackages() {
- // The logic here is (partially) copied and adapted from
- // system/apex/apexd/apexd.cpp.
- //
- // Only scan the APEX directory under /system, /system_ext and /vendor (within the chroot dir).
- std::vector<std::string> apex_dirs{apex::kApexPackageSystemDir, apex::kApexPackageSystemExtDir,
- apex::kApexPackageVendorDir};
- // Initialize ApexFileRepository used internally in ScanPackagesDirAndActivate.
- // This is a quick fix to fix apex activation in otapreopt_chroot.
- apex::ApexFileRepository::GetInstance().AddPreInstalledApex(apex_dirs);
- for (const auto& dir : apex_dirs) {
- // Cast call to void to suppress warn_unused_result.
- static_cast<void>(apex::ScanPackagesDirAndActivate(dir.c_str()));
+static void ActivateApexPackages() {
+ std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"};
+ std::string apexd_error_msg;
+
+ bool exec_result = Exec(apexd_cmd, &apexd_error_msg);
+ if (!exec_result) {
+ PLOG(ERROR) << "Running otapreopt failed: " << apexd_error_msg;
+ exit(220);
}
- return apex::GetActivePackages();
}
-static void CreateApexInfoList(const std::vector<apex::ApexFile>& apex_files) {
- // Setup the apex-info-list.xml file
- const std::string apex_info_file = std::string(apex::kApexRoot) + "/" + apex::kApexInfoList;
- std::fstream xml(apex_info_file.c_str(), std::ios::out | std::ios::trunc);
- if (!xml.is_open()) {
- PLOG(ERROR) << "Failed to open " << apex_info_file;
- exit(216);
- }
-
- // we do not care about inactive apexs
- std::vector<apex::ApexFile> inactive;
- apex::CollectApexInfoList(xml, apex_files, inactive);
- xml.flush();
- xml.close();
-}
-
-static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
- for (const apex::ApexFile& apex_file : active_packages) {
- const std::string& package_path = apex_file.GetPath();
- base::Result<void> status = apex::DeactivatePackage(package_path);
- if (!status.ok()) {
- LOG(ERROR) << "Failed to deactivate " << package_path << ": "
- << status.error();
- }
+static void DeactivateApexPackages() {
+ std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--unmount-all"};
+ std::string apexd_error_msg;
+ bool exec_result = Exec(apexd_cmd, &apexd_error_msg);
+ if (!exec_result) {
+ PLOG(ERROR) << "Running /system/bin/apexd --unmount-all failed: " << apexd_error_msg;
}
}
@@ -205,6 +179,11 @@
// want it for product APKs. Same notes as vendor above.
TryExtraMount("product", arg[2], "/postinstall/product");
+ // Try to mount the system_ext partition. update_engine doesn't do this for
+ // us, but we want it for system_ext APKs. Same notes as vendor and product
+ // above.
+ TryExtraMount("system_ext", arg[2], "/postinstall/system_ext");
+
constexpr const char* kPostInstallLinkerconfig = "/postinstall/linkerconfig";
// Try to mount /postinstall/linkerconfig. we will set it up after performing the chroot
if (mount("tmpfs", kPostInstallLinkerconfig, "tmpfs", 0, nullptr) != 0) {
@@ -267,27 +246,57 @@
exit(205);
}
+ // Call apexd --unmount-all to free up loop and dm block devices, so that we can re-use
+ // them during the next invocation. Since otapreopt_chroot calls exit in case something goes
+ // wrong we need to register our own atexit handler.
+ // We want to register this handler before actually activating apex packages. This is mostly
+ // due to the fact that if fail to unmount apexes, then on the next run of otapreopt_chroot
+ // we will ask for new loop devices instead of re-using existing ones, and we really don't want
+ // to do that. :)
+ if (atexit(DeactivateApexPackages) != 0) {
+ LOG(ERROR) << "Failed to register atexit hander";
+ exit(206);
+ }
+
// Try to mount APEX packages in "/apex" in the chroot dir. We need at least
// the ART APEX, as it is required by otapreopt to run dex2oat.
- std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
- CreateApexInfoList(active_packages);
+ ActivateApexPackages();
+ auto cleanup = android::base::make_scope_guard([](){
+ std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--unmount-all"};
+ std::string apexd_error_msg;
+ bool exec_result = Exec(apexd_cmd, &apexd_error_msg);
+ if (!exec_result) {
+ PLOG(ERROR) << "Running /system/bin/apexd --unmount-all failed: " << apexd_error_msg;
+ }
+ });
// Check that an ART APEX has been activated; clean up and exit
// early otherwise.
static constexpr const std::string_view kRequiredApexs[] = {
"com.android.art",
"com.android.runtime",
};
- for (std::string_view apex : kRequiredApexs) {
- if (std::none_of(active_packages.begin(), active_packages.end(),
- [&](const apex::ApexFile& package) {
- return package.GetManifest().name() == apex;
- })) {
- LOG(FATAL_WITHOUT_ABORT) << "No activated " << apex << " APEX package.";
- DeactivateApexPackages(active_packages);
- exit(217);
+ std::array<bool, arraysize(kRequiredApexs)> found_apexs{ false, false };
+ DIR* apex_dir = opendir("/apex");
+ if (apex_dir == nullptr) {
+ PLOG(ERROR) << "unable to open /apex";
+ exit(220);
+ }
+ for (dirent* entry = readdir(apex_dir); entry != nullptr; entry = readdir(apex_dir)) {
+ for (int i = 0; i < found_apexs.size(); i++) {
+ if (kRequiredApexs[i] == std::string_view(entry->d_name)) {
+ found_apexs[i] = true;
+ break;
+ }
}
}
+ closedir(apex_dir);
+ auto it = std::find(found_apexs.cbegin(), found_apexs.cend(), false);
+ if (it != found_apexs.cend()) {
+ LOG(ERROR) << "No activated " << kRequiredApexs[std::distance(found_apexs.cbegin(), it)]
+ << " package!";
+ exit(221);
+ }
// Setup /linkerconfig. Doing it after the chroot means it doesn't need its own category
if (selinux_android_restorecon("/linkerconfig", 0) < 0) {
@@ -323,9 +332,6 @@
LOG(ERROR) << "Running otapreopt failed: " << error_msg;
}
- // Tear down the work down by the apexd logic. (i.e. deactivate packages).
- DeactivateApexPackages(active_packages);
-
if (!exec_result) {
exit(213);
}
diff --git a/cmds/installd/run_dex2oat.cpp b/cmds/installd/run_dex2oat.cpp
index 17ea903..a27fd10 100644
--- a/cmds/installd/run_dex2oat.cpp
+++ b/cmds/installd/run_dex2oat.cpp
@@ -86,7 +86,7 @@
bool generate_compact_dex,
bool use_jitzygote_image,
const char* compilation_reason) {
- PrepareBootImageAndBootClasspathFlags(use_jitzygote_image);
+ PrepareBootImageFlags(use_jitzygote_image);
PrepareInputFileFlags(output_oat, output_vdex, output_image, input_dex, input_vdex,
dex_metadata, profile, swap_fd, class_loader_context,
@@ -112,7 +112,7 @@
RunDex2Oat::~RunDex2Oat() {}
-void RunDex2Oat::PrepareBootImageAndBootClasspathFlags(bool use_jitzygote_image) {
+void RunDex2Oat::PrepareBootImageFlags(bool use_jitzygote_image) {
std::string boot_image;
if (use_jitzygote_image) {
boot_image = StringPrintf("--boot-image=%s", kJitZygoteImage);
@@ -120,23 +120,6 @@
boot_image = MapPropertyToArg("dalvik.vm.boot-image", "--boot-image=%s");
}
AddArg(boot_image);
-
- // If DEX2OATBOOTCLASSPATH is not in the environment, dex2oat is going to query
- // BOOTCLASSPATH.
- char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH");
- if (dex2oat_bootclasspath != nullptr) {
- AddRuntimeArg(StringPrintf("-Xbootclasspath:%s", dex2oat_bootclasspath));
- }
-
- std::string updatable_bcp_packages =
- MapPropertyToArg("dalvik.vm.dex2oat-updatable-bcp-packages-file",
- "--updatable-bcp-packages-file=%s");
- if (updatable_bcp_packages.empty()) {
- // Make dex2oat fail by providing non-existent file name.
- updatable_bcp_packages =
- "--updatable-bcp-packages-file=/nonx/updatable-bcp-packages.txt";
- }
- AddArg(updatable_bcp_packages);
}
void RunDex2Oat::PrepareInputFileFlags(const UniqueFile& output_oat,
diff --git a/cmds/installd/run_dex2oat.h b/cmds/installd/run_dex2oat.h
index 325a3a2..475e124 100644
--- a/cmds/installd/run_dex2oat.h
+++ b/cmds/installd/run_dex2oat.h
@@ -56,7 +56,7 @@
void Exec(int exit_code);
protected:
- void PrepareBootImageAndBootClasspathFlags(bool use_jitzygote_image);
+ void PrepareBootImageFlags(bool use_jitzygote_image);
void PrepareInputFileFlags(const UniqueFile& output_oat,
const UniqueFile& output_vdex,
const UniqueFile& output_image,
diff --git a/cmds/installd/run_dex2oat_test.cpp b/cmds/installd/run_dex2oat_test.cpp
index 3813cf7..0a638cd 100644
--- a/cmds/installd/run_dex2oat_test.cpp
+++ b/cmds/installd/run_dex2oat_test.cpp
@@ -175,8 +175,6 @@
default_expected_flags_["--swap-fd"] = FLAG_UNUSED;
default_expected_flags_["--class-loader-context"] = FLAG_UNUSED;
default_expected_flags_["--class-loader-context-fds"] = FLAG_UNUSED;
- default_expected_flags_["--updatable-bcp-packages-file"] =
- "=/nonx/updatable-bcp-packages.txt";
// Arch
default_expected_flags_["--instruction-set"] = "=arm64";
@@ -320,28 +318,6 @@
VerifyExpectedFlags();
}
-TEST_F(RunDex2OatTest, DEX2OATBOOTCLASSPATH) {
- ASSERT_EQ(nullptr, getenv("DEX2OATBOOTCLASSPATH"));
- ASSERT_EQ(0, setenv("DEX2OATBOOTCLASSPATH", "foobar", /*override=*/ false))
- << "Failed to setenv: " << strerror(errno);
-
- CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
-
- SetExpectedFlagUsed("-Xbootclasspath", ":foobar");
- VerifyExpectedFlags();
-
- ASSERT_EQ(0, unsetenv("DEX2OATBOOTCLASSPATH"))
- << "Failed to setenv: " << strerror(errno);
-}
-
-TEST_F(RunDex2OatTest, UpdatableBootClassPath) {
- setSystemProperty("dalvik.vm.dex2oat-updatable-bcp-packages-file", "/path/to/file");
- CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
-
- SetExpectedFlagUsed("--updatable-bcp-packages-file", "=/path/to/file");
- VerifyExpectedFlags();
-}
-
TEST_F(RunDex2OatTest, DoNotGenerateCompactDex) {
auto args = RunDex2OatArgs::MakeDefaultTestArgs();
args->generate_compact_dex = false;
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index fbf1e0c..e272025 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -351,7 +351,7 @@
uid = kTestAppUid;
}
if (class_loader_context == nullptr) {
- class_loader_context = "&";
+ class_loader_context = "PCL[]";
}
int32_t dexopt_needed = 0; // does not matter;
std::optional<std::string> out_path; // does not matter
@@ -478,7 +478,7 @@
bool should_binder_call_succeed,
/*out */ binder::Status* binder_result) {
std::optional<std::string> out_path = oat_dir ? std::make_optional<std::string>(oat_dir) : std::nullopt;
- std::string class_loader_context = "&";
+ std::string class_loader_context = "PCL[]";
int32_t target_sdk_version = 0; // default
std::string profile_name = "primary.prof";
std::optional<std::string> dm_path_opt = dm_path ? std::make_optional<std::string>(dm_path) : std::nullopt;
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index c47df52..c4ecd07 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -1062,6 +1062,8 @@
static const char* kProcFilesystems = "/proc/filesystems";
bool supports_sdcardfs() {
+ if (!property_get_bool("external_storage.sdcardfs.enabled", true))
+ return false;
std::string supported;
if (!android::base::ReadFileToString(kProcFilesystems, &supported)) {
PLOG(ERROR) << "Failed to read supported filesystems";
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index b6ff28d..7c1ca91 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -508,10 +508,10 @@
EXPECT_THAT(output, HasSubstr("a.h.foo6@6.0::IFoo/6"));
EXPECT_EQ("", err.str());
+ std::string error;
vintf::HalManifest m;
- EXPECT_EQ(true, vintf::gHalManifestConverter(&m, out.str()))
- << "--init-vintf does not emit valid HAL manifest: "
- << vintf::gHalManifestConverter.lastError();
+ EXPECT_EQ(true, vintf::gHalManifestConverter(&m, out.str(), &error))
+ << "--init-vintf does not emit valid HAL manifest: " << error;
}
// test default columns
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 9de344a..3ebdeee 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -14,6 +14,7 @@
"-Wall",
"-Wextra",
"-Werror",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
srcs: [
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 0dbab4e..2f55249 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -239,7 +239,8 @@
#endif // !VENDORSERVICEMANAGER
// implicitly unlinked when the binder is removed
- if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {
+ if (binder->remoteBinder() != nullptr &&
+ binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
@@ -307,7 +308,9 @@
return Status::fromExceptionCode(Status::EX_NULL_POINTER);
}
- if (OK != IInterface::asBinder(callback)->linkToDeath(this)) {
+ if (OK !=
+ IInterface::asBinder(callback)->linkToDeath(
+ sp<ServiceManager>::fromExisting(this))) {
LOG(ERROR) << "Could not linkToDeath when adding " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
@@ -461,7 +464,8 @@
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
- if (OK != IInterface::asBinder(cb)->linkToDeath(this)) {
+ if (OK !=
+ IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}
@@ -491,7 +495,7 @@
}
ssize_t ServiceManager::Service::getNodeStrongRefCount() {
- sp<BpBinder> bpBinder = binder->remoteBinder();
+ sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
if (bpBinder == nullptr) return -1;
return ProcessState::self()->getStrongRefCountForNode(bpBinder);
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index 627dfe6..8c1beac 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -39,7 +39,7 @@
class BinderCallback : public LooperCallback {
public:
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
- sp<BinderCallback> cb = new BinderCallback;
+ sp<BinderCallback> cb = sp<BinderCallback>::make();
int binder_fd = -1;
IPCThreadState::self()->setupPolling(&binder_fd);
@@ -65,7 +65,7 @@
class ClientCallbackCallback : public LooperCallback {
public:
static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
- sp<ClientCallbackCallback> cb = new ClientCallbackCallback(manager);
+ sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager);
int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno);
@@ -105,6 +105,7 @@
return 1; // Continue receiving callbacks.
}
private:
+ friend sp<ClientCallbackCallback>;
ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
sp<ServiceManager> mManager;
};
@@ -120,7 +121,7 @@
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
- sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
+ sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index fb9f9df..5d5a75e 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -46,7 +46,7 @@
}
};
- return new LinkableBinder;
+ return sp<LinkableBinder>::make();
}
class MockAccess : public Access {
@@ -71,7 +71,7 @@
ON_CALL(*access, canFind(_, _)).WillByDefault(Return(true));
ON_CALL(*access, canList(_)).WillByDefault(Return(true));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
return sm;
}
@@ -119,7 +119,7 @@
.uid = uid,
}));
EXPECT_CALL(*access, canAdd(_, _)).Times(0);
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
@@ -161,7 +161,7 @@
EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{}));
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(false));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
@@ -194,7 +194,7 @@
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(false));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
@@ -218,7 +218,7 @@
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
sp<IBinder> service = getBinder();
EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/,
@@ -244,7 +244,7 @@
// TODO(b/136023468): when security check is first, this should be called first
// EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
@@ -261,7 +261,7 @@
EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{}));
EXPECT_CALL(*access, canList(_)).WillOnce(Return(false));
- sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access));
+ sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
std::vector<std::string> out;
EXPECT_FALSE(sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL, &out).isOk());
@@ -329,9 +329,9 @@
EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{}));
EXPECT_CALL(*access, canFind(_,_)).WillOnce(Return(false));
- sp<ServiceManager> sm = new ServiceManager(std::move(access));
+ sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access));
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(),
Status::EX_SECURITY);
@@ -343,9 +343,9 @@
EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{}));
EXPECT_CALL(*access, canFind(_,_)).WillOnce(Return(false));
- sp<ServiceManager> sm = new ServiceManager(std::move(access));
+ sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access));
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
// should always hit security error first
EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(),
@@ -355,7 +355,7 @@
TEST(ServiceNotifications, InvalidName) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
EXPECT_EQ(sm->registerForNotifications("foo@foo", cb).exceptionCode(),
Status::EX_ILLEGAL_ARGUMENT);
@@ -371,7 +371,7 @@
TEST(ServiceNotifications, Unregister) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
EXPECT_TRUE(sm->registerForNotifications("foofoo", cb).isOk());
EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(), 0);
@@ -380,7 +380,7 @@
TEST(ServiceNotifications, UnregisterWhenNoRegistrationExists) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(),
Status::EX_ILLEGAL_STATE);
@@ -389,7 +389,7 @@
TEST(ServiceNotifications, NoNotification) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
EXPECT_TRUE(sm->registerForNotifications("foofoo", cb).isOk());
EXPECT_TRUE(sm->addService("otherservice", getBinder(),
@@ -402,7 +402,7 @@
TEST(ServiceNotifications, GetNotification) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
sp<IBinder> service = getBinder();
@@ -417,7 +417,7 @@
TEST(ServiceNotifications, GetNotificationForAlreadyRegisteredService) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
sp<IBinder> service = getBinder();
@@ -433,7 +433,7 @@
TEST(ServiceNotifications, GetMultipleNotification) {
auto sm = getPermissiveServiceManager();
- sp<CallbackHistorian> cb = new CallbackHistorian;
+ sp<CallbackHistorian> cb = sp<CallbackHistorian>::make();
sp<IBinder> binder1 = getBinder();
sp<IBinder> binder2 = getBinder();
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 49cb098..cba8207 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -58,21 +58,11 @@
// transport itself and should be moved to AIDL or in domain-specific libs.
//
// Currently, these are only on system android (not vendor, not host)
+// TODO(b/183654927) - move these into separate libraries
libbinder_device_interface_sources = [
- "ActivityManager.cpp",
- "AppOpsManager.cpp",
- "IActivityManager.cpp",
- "IAppOpsCallback.cpp",
- "IAppOpsService.cpp",
- "IBatteryStats.cpp",
- "IMediaResourceMonitor.cpp",
"IPermissionController.cpp",
- "IProcessInfoService.cpp",
- "IUidObserver.cpp",
"PermissionCache.cpp",
"PermissionController.cpp",
- "ProcessInfoService.cpp",
- "IpPrefix.cpp",
]
cc_library {
@@ -169,6 +159,7 @@
"-Werror",
"-Wzero-as-null-pointer-constant",
"-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
product_variables: {
binder32bit: {
@@ -265,3 +256,56 @@
},
},
}
+
+// libbinder historically contained additional interfaces that provided specific
+// functionality in the platform but have nothing to do with binder itself. These
+// are moved out of libbinder in order to avoid the overhead of their vtables.
+// If you are working on or own one of these interfaces, the responsible things
+// to would be:
+// - give them a new home
+// - convert them to AIDL instead of having manually written parceling code
+
+cc_library {
+ name: "libbatterystats_aidl",
+ srcs: [
+ "IBatteryStats.cpp",
+ ],
+ export_include_dirs: ["include_batterystats"],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ ],
+}
+
+cc_library {
+ name: "libprocessinfoservice_aidl",
+ srcs: [
+ "IProcessInfoService.cpp",
+ "ProcessInfoService.cpp",
+ ],
+ export_include_dirs: ["include_processinfo"],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "liblog",
+ ],
+}
+
+cc_library {
+ name: "libactivitymanager_aidl",
+ srcs: [
+ "ActivityManager.cpp",
+ "IActivityManager.cpp",
+ "IUidObserver.cpp",
+ ":activity_manager_procstate_aidl",
+ ],
+ export_include_dirs: ["include_activitymanager"],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "liblog",
+ ],
+ aidl: {
+ export_aidl_headers: true,
+ },
+}
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 825a821..fdcf94a 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -107,8 +107,7 @@
// ---------------------------------------------------------------------------
-
-BpBinder* BpBinder::create(int32_t handle) {
+sp<BpBinder> BpBinder::create(int32_t handle) {
int32_t trackedUid = -1;
if (sCountByUidEnabled) {
trackedUid = IPCThreadState::self()->getCallingUid();
@@ -134,10 +133,10 @@
}
sTrackingMap[trackedUid]++;
}
- return new BpBinder(BinderHandle{handle}, trackedUid);
+ return sp<BpBinder>::make(BinderHandle{handle}, trackedUid);
}
-BpBinder* BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) {
+sp<BpBinder> BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) {
LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection");
// These are not currently tracked, since there is no UID or other
@@ -145,7 +144,7 @@
// needed, connection objects keep track of all BpBinder objects on a
// per-connection basis.
- return new BpBinder(SocketHandle{connection, address});
+ return sp<BpBinder>::make(SocketHandle{connection, address});
}
BpBinder::BpBinder(Handle&& handle)
@@ -194,10 +193,13 @@
const String16& BpBinder::getInterfaceDescriptor() const
{
if (isDescriptorCached() == false) {
- Parcel send, reply;
+ sp<BpBinder> thiz = sp<BpBinder>::fromExisting(const_cast<BpBinder*>(this));
+
+ Parcel data;
+ data.markForBinder(thiz);
+ Parcel reply;
// do the IPC without a lock held.
- status_t err = const_cast<BpBinder*>(this)->transact(
- INTERFACE_TRANSACTION, send, &reply);
+ status_t err = thiz->transact(INTERFACE_TRANSACTION, data, &reply);
if (err == NO_ERROR) {
String16 res(reply.readString16());
Mutex::Autolock _l(mLock);
@@ -223,7 +225,7 @@
status_t BpBinder::pingBinder()
{
Parcel data;
- data.markForBinder(this);
+ data.markForBinder(sp<BpBinder>::fromExisting(this));
Parcel reply;
return transact(PING_TRANSACTION, data, &reply);
}
@@ -400,7 +402,7 @@
ALOGV("Reporting death to recipient: %p\n", recipient.get());
if (recipient == nullptr) return;
- recipient->binderDied(this);
+ recipient->binderDied(wp<BpBinder>::fromExisting(this));
}
diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp
index 349658e..a90bfd2 100644
--- a/libs/binder/BufferedTextOutput.cpp
+++ b/libs/binder/BufferedTextOutput.cpp
@@ -254,7 +254,7 @@
BufferState* bs = ts.states[mIndex].get();
if (bs != nullptr && bs->seq == mSeq) return bs;
- ts.states.editItemAt(mIndex) = new BufferState(mIndex);
+ ts.states.editItemAt(mIndex) = sp<BufferState>::make(mIndex);
bs = ts.states[mIndex].get();
if (bs != nullptr) return bs;
}
diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp
index d0085df..0de804c 100644
--- a/libs/binder/IBatteryStats.cpp
+++ b/libs/binder/IBatteryStats.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <binder/IBatteryStats.h>
+#include <batterystats/IBatteryStats.h>
#include <utils/Log.h>
#include <binder/Parcel.h>
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
index b19004d..2780bd4 100644
--- a/libs/binder/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -33,14 +33,14 @@
sp<IBinder> IInterface::asBinder(const IInterface* iface)
{
if (iface == nullptr) return nullptr;
- return const_cast<IInterface*>(iface)->onAsBinder();
+ return sp<IBinder>::fromExisting(const_cast<IInterface*>(iface)->onAsBinder());
}
// static
sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
{
if (iface == nullptr) return nullptr;
- return iface->onAsBinder();
+ return sp<IBinder>::fromExisting(iface->onAsBinder());
}
diff --git a/libs/binder/IMediaResourceMonitor.cpp b/libs/binder/IMediaResourceMonitor.cpp
deleted file mode 100644
index f5fa817..0000000
--- a/libs/binder/IMediaResourceMonitor.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <binder/IMediaResourceMonitor.h>
-#include <binder/Parcel.h>
-#include <utils/Errors.h>
-#include <sys/types.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpMediaResourceMonitor : public BpInterface<IMediaResourceMonitor> {
-public:
- explicit BpMediaResourceMonitor(const sp<IBinder>& impl)
- : BpInterface<IMediaResourceMonitor>(impl) {}
-
- virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaResourceMonitor::getInterfaceDescriptor());
- data.writeInt32(pid);
- data.writeInt32(type);
- remote()->transact(NOTIFY_RESOURCE_GRANTED, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(MediaResourceMonitor, "android.media.IMediaResourceMonitor")
-
-// ----------------------------------------------------------------------
-
-// NOLINTNEXTLINE(google-default-arguments)
-status_t BnMediaResourceMonitor::onTransact( uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags) {
- switch(code) {
- case NOTIFY_RESOURCE_GRANTED: {
- CHECK_INTERFACE(IMediaResourceMonitor, data, reply);
- int32_t pid = data.readInt32();
- const int32_t type = data.readInt32();
- notifyResourceGranted(/*in*/ pid, /*in*/ type);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------
-
-} // namespace android
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index cca8f81..bd974b0 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -68,7 +68,7 @@
// TODO: Reimplemement based on standard C++ container?
};
-static sp<HeapCache> gHeapCache = new HeapCache();
+static sp<HeapCache> gHeapCache = sp<HeapCache>::make();
/******************************************************************************/
@@ -288,7 +288,7 @@
int32_t heapId = mHeapId.load(memory_order_acquire);
if (heapId == -1) {
sp<IBinder> binder(IInterface::asBinder(const_cast<BpMemoryHeap*>(this)));
- sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
+ sp<BpMemoryHeap> heap = sp<BpMemoryHeap>::cast(find_heap(binder));
heap->assertReallyMapped();
if (heap->mBase != MAP_FAILED) {
Mutex::Autolock _l(mLock);
diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp
index 570edb9..d26754e 100644
--- a/libs/binder/IProcessInfoService.cpp
+++ b/libs/binder/IProcessInfoService.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <binder/IProcessInfoService.h>
+#include <processinfo/IProcessInfoService.h>
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <sys/types.h>
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index ca067e2..61f4581 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -102,7 +102,7 @@
}
}
- gDefaultServiceManager = new ServiceManagerShim(sm);
+ gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
});
return gDefaultServiceManager;
@@ -324,7 +324,7 @@
}
if (out != nullptr) return out;
- sp<Waiter> waiter = new Waiter;
+ sp<Waiter> waiter = sp<Waiter>::make();
if (!mTheRealServiceManager->registerForNotifications(
name, waiter).isOk()) {
return nullptr;
diff --git a/libs/binder/IpPrefix.cpp b/libs/binder/IpPrefix.cpp
deleted file mode 100644
index 4edc493..0000000
--- a/libs/binder/IpPrefix.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2015 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 "IpPrefix"
-
-#include <binder/IpPrefix.h>
-#include <vector>
-
-#include <binder/IBinder.h>
-#include <binder/Parcel.h>
-#include <log/log.h>
-#include <utils/Errors.h>
-
-using android::BAD_VALUE;
-using android::NO_ERROR;
-using android::Parcel;
-using android::status_t;
-
-namespace android {
-
-namespace net {
-
-#define RETURN_IF_FAILED(calledOnce) \
- { \
- status_t returnStatus = calledOnce; \
- if (returnStatus) { \
- ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
- return returnStatus; \
- } \
- }
-
-status_t IpPrefix::writeToParcel(Parcel* parcel) const {
- /*
- * Keep implementation in sync with writeToParcel() in
- * frameworks/base/core/java/android/net/IpPrefix.java.
- */
- std::vector<uint8_t> byte_vector;
-
- if (mIsIpv6) {
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr);
- byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
- } else {
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr);
- byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr));
- }
-
- RETURN_IF_FAILED(parcel->writeByteVector(byte_vector));
- RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength)));
-
- return NO_ERROR;
-}
-
-status_t IpPrefix::readFromParcel(const Parcel* parcel) {
- /*
- * Keep implementation in sync with readFromParcel() in
- * frameworks/base/core/java/android/net/IpPrefix.java.
- */
- std::vector<uint8_t> byte_vector;
-
- RETURN_IF_FAILED(parcel->readByteVector(&byte_vector));
- RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength));
-
- if (byte_vector.size() == 16) {
- mIsIpv6 = true;
- memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr));
-
- } else if (byte_vector.size() == 4) {
- mIsIpv6 = false;
- memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr));
-
- } else {
- ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
- return BAD_VALUE;
- }
-
- return NO_ERROR;
-}
-
-const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const
-{
- return mUnion.mIn6Addr;
-}
-
-const struct in_addr& IpPrefix::getAddressAsInAddr() const
-{
- return mUnion.mInAddr;
-}
-
-bool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const
-{
- if (isIpv6()) {
- *addr = mUnion.mIn6Addr;
- return true;
- }
- return false;
-}
-
-bool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const
-{
- if (isIpv4()) {
- *addr = mUnion.mInAddr;
- return true;
- }
- return false;
-}
-
-bool IpPrefix::isIpv6() const
-{
- return mIsIpv6;
-}
-
-bool IpPrefix::isIpv4() const
-{
- return !mIsIpv6;
-}
-
-int32_t IpPrefix::getPrefixLength() const
-{
- return mPrefixLength;
-}
-
-void IpPrefix::setAddress(const struct in6_addr& addr)
-{
- mUnion.mIn6Addr = addr;
- mIsIpv6 = true;
-}
-
-void IpPrefix::setAddress(const struct in_addr& addr)
-{
- mUnion.mInAddr = addr;
- mIsIpv6 = false;
-}
-
-void IpPrefix::setPrefixLength(int32_t prefix)
-{
- mPrefixLength = prefix;
-}
-
-bool operator==(const IpPrefix& lhs, const IpPrefix& rhs)
-{
- if (lhs.mIsIpv6 != rhs.mIsIpv6) {
- return false;
- }
-
- if (lhs.mPrefixLength != rhs.mPrefixLength) {
- return false;
- }
-
- if (lhs.mIsIpv6) {
- return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr));
- }
-
- return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr));
-}
-
-} // namespace net
-
-} // namespace android
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index f96b6bb..b503beb 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -129,7 +129,9 @@
}
if (!reRegister) {
- if(!manager->registerClientCallback(name, service, this).isOk()) {
+ if (!manager->registerClientCallback(name, service,
+ sp<android::os::IClientCallback>::fromExisting(this))
+ .isOk()) {
ALOGE("Failed to add client callback for service %s", name.c_str());
return false;
}
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index b46b3e8..c4475c7 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -228,10 +228,8 @@
// ----------------------------------------------------------------------------
MemoryDealer::MemoryDealer(size_t size, const char* name, uint32_t flags)
- : mHeap(new MemoryHeapBase(size, flags, name)),
- mAllocator(new SimpleBestFitAllocator(size))
-{
-}
+ : mHeap(sp<MemoryHeapBase>::make(size, flags, name)),
+ mAllocator(new SimpleBestFitAllocator(size)) {}
MemoryDealer::~MemoryDealer()
{
@@ -243,7 +241,7 @@
sp<IMemory> memory;
const ssize_t offset = allocator()->allocate(size);
if (offset >= 0) {
- memory = new Allocation(this, heap(), offset, size);
+ memory = sp<Allocation>::make(sp<MemoryDealer>::fromExisting(this), heap(), offset, size);
}
return memory;
}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 34a474b..98ca829 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -293,7 +293,8 @@
if (flat) {
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER: {
- sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
+ sp<IBinder> binder =
+ sp<IBinder>::fromExisting(reinterpret_cast<IBinder*>(flat->cookie));
return finishUnflattenBinder(binder, out);
}
case BINDER_TYPE_HANDLE: {
@@ -418,6 +419,11 @@
status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
{
+ if (parcel->isForRpc() != isForRpc()) {
+ ALOGE("Cannot append Parcel of one format to another.");
+ return BAD_TYPE;
+ }
+
status_t err;
const uint8_t *data = parcel->mData;
const binder_size_t *objects = parcel->mObjects;
@@ -555,12 +561,17 @@
}
void Parcel::markForBinder(const sp<IBinder>& binder) {
+ LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written");
+
if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) {
markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcConnection());
}
}
void Parcel::markForRpc(const sp<RpcConnection>& connection) {
+ LOG_ALWAYS_FATAL_IF(mData != nullptr && mOwner == nullptr,
+ "format must be set before data is written OR on IPC data");
+
LOG_ALWAYS_FATAL_IF(connection == nullptr, "markForRpc requires connection");
mConnection = connection;
}
@@ -2100,6 +2111,9 @@
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
const binder_size_t* objects, size_t objectsCount, release_func relFunc)
{
+ // this code uses 'mOwner == nullptr' to understand whether it owns memory
+ LOG_ALWAYS_FATAL_IF(relFunc == nullptr, "must provide cleanup function");
+
freeData();
mData = const_cast<uint8_t*>(data);
diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp
index f75141e..0fb954a 100644
--- a/libs/binder/ProcessInfoService.cpp
+++ b/libs/binder/ProcessInfoService.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <binder/ProcessInfoService.h>
+#include <processinfo/ProcessInfoService.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 82f6faf..a8b2fb2 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -105,7 +105,7 @@
}
std::lock_guard<std::mutex> l(gProcessMutex);
- gProcess = new ProcessState(driver);
+ gProcess = sp<ProcessState>::make(driver);
});
if (requireDefault) {
@@ -299,8 +299,8 @@
return nullptr;
}
- b = BpBinder::create(handle);
- e->binder = b;
+ sp<BpBinder> b = BpBinder::create(handle);
+ e->binder = b.get();
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
@@ -340,7 +340,7 @@
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
- sp<Thread> t = new PoolThread(isMain);
+ sp<Thread> t = sp<PoolThread>::make(isMain);
t->run(name.string());
}
}
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index 83a1618..4aff92b 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -20,6 +20,7 @@
#include <binder/Parcel.h>
#include <binder/Stability.h>
+#include <utils/String8.h>
#include "RpcState.h"
#include "RpcWireFormat.h"
@@ -29,14 +30,20 @@
#include <sys/un.h>
#include <unistd.h>
-#if defined(__GLIBC__)
+#ifdef __GLIBC__
extern "C" pid_t gettid();
#endif
+#ifdef __BIONIC__
+#include <linux/vm_sockets.h>
+#endif
+
namespace android {
using base::unique_fd;
+RpcConnection::SocketAddress::~SocketAddress() {}
+
RpcConnection::RpcConnection() {
LOG_RPC_DETAIL("RpcConnection created %p", this);
@@ -47,94 +54,108 @@
}
sp<RpcConnection> RpcConnection::make() {
- return new RpcConnection;
+ return sp<RpcConnection>::make();
}
+class UnixSocketAddress : public RpcConnection::SocketAddress {
+public:
+ explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
+ unsigned int pathLen = strlen(path) + 1;
+ LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s",
+ pathLen, path);
+ memcpy(mAddr.sun_path, path, pathLen);
+ }
+ virtual ~UnixSocketAddress() {}
+ std::string toString() const override {
+ return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)),
+ mAddr.sun_path)
+ .c_str();
+ }
+ const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
+ size_t addrSize() const override { return sizeof(mAddr); }
+
+private:
+ sockaddr_un mAddr;
+};
+
bool RpcConnection::setupUnixDomainServer(const char* path) {
- LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Only supports one server now");
-
- unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
- if (serverFd == -1) {
- ALOGE("Could not create socket at %s: %s", path, strerror(errno));
- return false;
- }
-
- struct sockaddr_un addr = {
- .sun_family = AF_UNIX,
- };
-
- unsigned int pathLen = strlen(path) + 1;
- LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen);
- memcpy(addr.sun_path, path, pathLen);
-
- if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) {
- ALOGE("Could not bind socket at %s: %s", path, strerror(errno));
- return false;
- }
-
- if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
- ALOGE("Could not listen socket at %s: %s", path, strerror(errno));
- return false;
- }
-
- mServer = std::move(serverFd);
- return true;
+ return setupSocketServer(UnixSocketAddress(path));
}
bool RpcConnection::addUnixDomainClient(const char* path) {
- LOG_RPC_DETAIL("Connecting on path: %s", path);
+ return addSocketClient(UnixSocketAddress(path));
+}
- unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+#ifdef __BIONIC__
+
+class VsockSocketAddress : public RpcConnection::SocketAddress {
+public:
+ VsockSocketAddress(unsigned int cid, unsigned int port)
+ : mAddr({
+ .svm_family = AF_VSOCK,
+ .svm_port = port,
+ .svm_cid = cid,
+ }) {}
+ virtual ~VsockSocketAddress() {}
+ std::string toString() const override {
+ return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str();
+ }
+ const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
+ size_t addrSize() const override { return sizeof(mAddr); }
+
+private:
+ sockaddr_vm mAddr;
+};
+
+bool RpcConnection::setupVsockServer(unsigned int port) {
+ // realizing value w/ this type at compile time to avoid ubsan abort
+ constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
+
+ return setupSocketServer(VsockSocketAddress(kAnyCid, port));
+}
+
+bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) {
+ return addSocketClient(VsockSocketAddress(cid, port));
+}
+
+#endif // __BIONIC__
+
+bool RpcConnection::addNullDebuggingClient() {
+ unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
+
if (serverFd == -1) {
- ALOGE("Could not create socket at %s: %s", path, strerror(errno));
+ ALOGE("Could not connect to /dev/null: %s", strerror(errno));
return false;
}
- struct sockaddr_un addr = {
- .sun_family = AF_UNIX,
- };
-
- unsigned int pathLen = strlen(path) + 1;
- LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen);
- memcpy(addr.sun_path, path, pathLen);
-
- if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) {
- ALOGE("Could not connect socket at %s: %s", path, strerror(errno));
- return false;
- }
-
- LOG_RPC_DETAIL("Unix domain client with fd %d", serverFd.get());
-
addClient(std::move(serverFd));
return true;
}
sp<IBinder> RpcConnection::getRootObject() {
- ExclusiveSocket socket(this, SocketUse::CLIENT);
- return state()->getRootObject(socket.fd(), this);
+ ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
+ return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
}
status_t RpcConnection::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
- ExclusiveSocket socket(this,
+ ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this),
(flags & IBinder::FLAG_ONEWAY) ? SocketUse::CLIENT_ASYNC
: SocketUse::CLIENT);
- return state()->transact(socket.fd(), address, code, data, this, reply, flags);
+ return state()->transact(socket.fd(), address, code, data,
+ sp<RpcConnection>::fromExisting(this), reply, flags);
}
status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
- ExclusiveSocket socket(this, SocketUse::CLIENT_REFCOUNT);
+ ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT_REFCOUNT);
return state()->sendDecStrong(socket.fd(), address);
}
void RpcConnection::join() {
// establish a connection
{
- struct sockaddr_un clientSa;
- socklen_t clientSaLen = sizeof(clientSa);
-
- unique_fd clientFd(TEMP_FAILURE_RETRY(
- accept4(mServer.get(), (struct sockaddr*)&clientSa, &clientSaLen, SOCK_CLOEXEC)));
+ unique_fd clientFd(
+ TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC)));
if (clientFd < 0) {
// If this log becomes confusing, should save more state from setupUnixDomainServer
// in order to output here.
@@ -144,16 +165,17 @@
LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
- addServer(std::move(clientFd));
+ assignServerToThisThread(std::move(clientFd));
}
// We may not use the connection we just established (two threads might
// establish connections for each other), but for now, just use one
// server/socket connection.
- ExclusiveSocket socket(this, SocketUse::SERVER);
+ ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::SERVER);
while (true) {
- status_t error = state()->getAndExecuteCommand(socket.fd(), this);
+ status_t error =
+ state()->getAndExecuteCommand(socket.fd(), sp<RpcConnection>::fromExisting(this));
if (error != OK) {
ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
@@ -170,16 +192,63 @@
return mForServer;
}
-void RpcConnection::addClient(base::unique_fd&& fd) {
+bool RpcConnection::setupSocketServer(const SocketAddress& addr) {
+ LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");
+
+ unique_fd serverFd(
+ TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+ if (serverFd == -1) {
+ ALOGE("Could not create socket: %s", strerror(errno));
+ return false;
+ }
+
+ if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
+ int savedErrno = errno;
+ ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
+ return false;
+ }
+
+ if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
+ int savedErrno = errno;
+ ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
+ return false;
+ }
+
+ mServer = std::move(serverFd);
+ return true;
+}
+
+bool RpcConnection::addSocketClient(const SocketAddress& addr) {
+ unique_fd serverFd(
+ TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+ if (serverFd == -1) {
+ int savedErrno = errno;
+ ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
+ return false;
+ }
+
+ if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
+ int savedErrno = errno;
+ ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
+ return false;
+ }
+
+ LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
+
+ addClient(std::move(serverFd));
+ return true;
+}
+
+void RpcConnection::addClient(unique_fd&& fd) {
std::lock_guard<std::mutex> _l(mSocketMutex);
- sp<ConnectionSocket> connection = new ConnectionSocket();
+ sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
connection->fd = std::move(fd);
mClients.push_back(connection);
}
-void RpcConnection::addServer(base::unique_fd&& fd) {
+void RpcConnection::assignServerToThisThread(unique_fd&& fd) {
std::lock_guard<std::mutex> _l(mSocketMutex);
- sp<ConnectionSocket> connection = new ConnectionSocket();
+ sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
connection->fd = std::move(fd);
mServers.push_back(connection);
}
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index df07916..1fa37ba 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -36,7 +36,7 @@
RpcServer::~RpcServer() {}
sp<RpcServer> RpcServer::make() {
- return new RpcServer;
+ return sp<RpcServer>::make();
}
void RpcServer::iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction() {
@@ -47,7 +47,7 @@
LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
auto connection = RpcConnection::make();
- connection->setForServer(this);
+ connection->setForServer(sp<RpcServer>::fromExisting(this));
mConnections.push_back(connection);
return connection;
}
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 64e842e..d934136 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -40,7 +40,7 @@
// We need to be able to send instructions over the socket for how to
// connect to a different server, and we also need to let the host
// process know that this is happening.
- ALOGE("Canot send binder from unrelated binder RPC connection.");
+ ALOGE("Cannot send binder from unrelated binder RPC connection.");
return INVALID_OPERATION;
}
@@ -192,7 +192,7 @@
return false;
}
- ssize_t sent = TEMP_FAILURE_RETRY(send(fd.get(), data, size, 0));
+ ssize_t sent = TEMP_FAILURE_RETRY(send(fd.get(), data, size, MSG_NOSIGNAL));
if (sent < 0 || sent != static_cast<ssize_t>(size)) {
ALOGE("Failed to send %s (sent %zd of %zu bytes) on fd %d, error: %s", what, sent, size,
@@ -212,7 +212,7 @@
return false;
}
- ssize_t recd = TEMP_FAILURE_RETRY(recv(fd.get(), data, size, MSG_WAITALL));
+ ssize_t recd = TEMP_FAILURE_RETRY(recv(fd.get(), data, size, MSG_WAITALL | MSG_NOSIGNAL));
if (recd < 0 || recd != static_cast<ssize_t>(size)) {
terminate();
@@ -312,8 +312,8 @@
return waitForReply(fd, connection, reply);
}
-static void cleanup_data(Parcel* p, const uint8_t* data, size_t dataSize,
- const binder_size_t* objects, size_t objectsCount) {
+static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,
+ const binder_size_t* objects, size_t objectsCount) {
(void)p;
delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data));
(void)dataSize;
@@ -351,7 +351,7 @@
if (rpcReply->status != OK) return rpcReply->status;
reply->ipcSetDataReference(rpcReply->data, command.bodySize - offsetof(RpcWireReply, data),
- nullptr, 0, cleanup_data);
+ nullptr, 0, cleanup_reply_data);
reply->markForRpc(connection);
@@ -427,6 +427,15 @@
return processTransactInternal(fd, connection, std::move(transactionData));
}
+static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
+ const binder_size_t* objects, size_t objectsCount) {
+ (void)p;
+ (void)data;
+ (void)dataSize;
+ (void)objects;
+ (void)objectsCount;
+}
+
status_t RpcState::processTransactInternal(const base::unique_fd& fd,
const sp<RpcConnection>& connection,
std::vector<uint8_t>&& transactionData) {
@@ -489,14 +498,20 @@
}
}
- Parcel data;
- data.setData(transaction->data, transactionData.size() - offsetof(RpcWireTransaction, data));
- data.markForRpc(connection);
-
Parcel reply;
reply.markForRpc(connection);
if (replyStatus == OK) {
+ Parcel data;
+ // transaction->data is owned by this function. Parcel borrows this data and
+ // only holds onto it for the duration of this function call. Parcel will be
+ // deleted before the 'transactionData' object.
+ data.ipcSetDataReference(transaction->data,
+ transactionData.size() - offsetof(RpcWireTransaction, data),
+ nullptr /*object*/, 0 /*objectCount*/,
+ do_nothing_to_transact_data);
+ data.markForRpc(connection);
+
if (target) {
replyStatus = target->transact(transaction->code, data, &reply, transaction->flags);
} else {
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 06830c0..709cf67 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -38,18 +38,30 @@
};
}
-void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) {
+void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
// Downgrading a remote binder would require also copying the version from
// the binder sent here. In practice though, we don't need to downgrade the
// stability of a remote binder, since this would as an effect only restrict
// what we can do to it.
LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
- auto stability = Category::currentFromLevel(getLocalLevel());
+ auto stability = Category::currentFromLevel(level);
status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}
+void Stability::forceDowngradeToLocalStability(const sp<IBinder>& binder) {
+ forceDowngradeToStability(binder, getLocalLevel());
+}
+
+void Stability::forceDowngradeToSystemStability(const sp<IBinder>& binder) {
+ forceDowngradeToStability(binder, Level::SYSTEM);
+}
+
+void Stability::forceDowngradeToVendorStability(const sp<IBinder>& binder) {
+ forceDowngradeToStability(binder, Level::VENDOR);
+}
+
std::string Stability::Category::debugString() {
return levelString(level) + " wire protocol version "
+ std::to_string(version);
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 7079544..7e9be41 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -131,8 +131,8 @@
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
- inline IBinder* remote() { return mRemote; }
- inline IBinder* remote() const { return mRemote; }
+ inline IBinder* remote() const { return mRemote; }
+ inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); }
private:
BpRefBase(const BpRefBase& o);
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 8ab7893..ad618f9 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -40,8 +40,8 @@
class BpBinder : public IBinder
{
public:
- static BpBinder* create(int32_t handle);
- static BpBinder* create(const sp<RpcConnection>& connection, const RpcAddress& address);
+ static sp<BpBinder> create(int32_t handle);
+ static sp<BpBinder> create(const sp<RpcConnection>& connection, const RpcAddress& address);
/**
* Return value:
@@ -143,6 +143,7 @@
private:
friend PrivateAccessorForId;
+ friend class sp<BpBinder>;
struct BinderHandle {
int32_t handle;
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index f4a21dd..f35e2db 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -143,11 +143,10 @@
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != nullptr) { \
- intr = static_cast<I##INTERFACE*>( \
- obj->queryLocalInterface( \
- I##INTERFACE::descriptor).get()); \
+ intr = ::android::sp<I##INTERFACE>::cast( \
+ obj->queryLocalInterface(I##INTERFACE::descriptor)); \
if (intr == nullptr) { \
- intr = new Bp##INTERFACE(obj); \
+ intr = ::android::sp<Bp##INTERFACE>::make(obj); \
} \
} \
return intr; \
@@ -186,7 +185,7 @@
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
const String16& _descriptor)
{
- if (_descriptor == INTERFACE::descriptor) return this;
+ if (_descriptor == INTERFACE::descriptor) return sp<IInterface>::fromExisting(this);
return nullptr;
}
diff --git a/libs/binder/include/binder/IMediaResourceMonitor.h b/libs/binder/include/binder/IMediaResourceMonitor.h
deleted file mode 100644
index f92d557..0000000
--- a/libs/binder/include/binder/IMediaResourceMonitor.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#ifndef __ANDROID_VNDK__
-
-#include <binder/IInterface.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class IMediaResourceMonitor : public IInterface {
-public:
- DECLARE_META_INTERFACE(MediaResourceMonitor)
-
- // Values should be in sync with Intent.EXTRA_MEDIA_RESOURCE_TYPE_XXX.
- enum {
- TYPE_VIDEO_CODEC = 0,
- TYPE_AUDIO_CODEC = 1,
- };
-
- virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0;
-
- enum {
- NOTIFY_RESOURCE_GRANTED = IBinder::FIRST_CALL_TRANSACTION,
- };
-};
-
-// ----------------------------------------------------------------------
-
-class BnMediaResourceMonitor : public BnInterface<IMediaResourceMonitor> {
-public:
- // NOLINTNEXTLINE(google-default-arguments)
- virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------
-
-} // namespace android
-
-#else // __ANDROID_VNDK__
-#error "This header is not visible to vendors"
-#endif // __ANDROID_VNDK__
diff --git a/libs/binder/include/binder/IpPrefix.h b/libs/binder/include/binder/IpPrefix.h
deleted file mode 100644
index a8faa3f..0000000
--- a/libs/binder/include/binder/IpPrefix.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 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
-
-#ifndef __ANDROID_VNDK__
-
-#include <netinet/in.h>
-
-#include <binder/Parcelable.h>
-#include <utils/String16.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-
-namespace net {
-
-/*
- * C++ implementation of the Java class android.net.IpPrefix
- */
-class IpPrefix : public Parcelable {
-public:
- IpPrefix() = default;
- virtual ~IpPrefix() = default;
- IpPrefix(const IpPrefix& prefix) = default;
-
- IpPrefix(const struct in6_addr& addr, int32_t plen):
- mUnion(addr), mPrefixLength(plen), mIsIpv6(true) { }
-
- IpPrefix(const struct in_addr& addr, int32_t plen):
- mUnion(addr), mPrefixLength(plen), mIsIpv6(false) { }
-
- bool getAddressAsIn6Addr(struct in6_addr* addr) const;
- bool getAddressAsInAddr(struct in_addr* addr) const;
-
- const struct in6_addr& getAddressAsIn6Addr() const;
- const struct in_addr& getAddressAsInAddr() const;
-
- bool isIpv6() const;
- bool isIpv4() const;
-
- int32_t getPrefixLength() const;
-
- void setAddress(const struct in6_addr& addr);
- void setAddress(const struct in_addr& addr);
-
- void setPrefixLength(int32_t prefix);
-
- friend bool operator==(const IpPrefix& lhs, const IpPrefix& rhs);
-
- friend bool operator!=(const IpPrefix& lhs, const IpPrefix& rhs) {
- return !(lhs == rhs);
- }
-
-public:
- // Overrides
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
-
-private:
- union InternalUnion {
- InternalUnion() = default;
- explicit InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { }
- explicit InternalUnion(const struct in_addr &addr):mInAddr(addr) { }
- struct in6_addr mIn6Addr;
- struct in_addr mInAddr;
- } mUnion;
- int32_t mPrefixLength;
- bool mIsIpv6;
-};
-
-} // namespace net
-
-} // namespace android
-
-#else // __ANDROID_VNDK__
-#error "This header is not visible to vendors"
-#endif // __ANDROID_VNDK__
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 2405ab6..0919648 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -88,7 +88,8 @@
static sp<ProcessState> init(const char *defaultDriver, bool requireDefault);
friend class IPCThreadState;
-
+ friend class sp<ProcessState>;
+
explicit ProcessState(const char* driver);
~ProcessState();
@@ -124,7 +125,6 @@
Vector<handle_entry>mHandleToObject;
- String8 mRootDir;
bool mThreadPoolStarted;
volatile int32_t mThreadPoolSeq;
diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h
index 65c5232..dba47b4 100644
--- a/libs/binder/include/binder/RpcConnection.h
+++ b/libs/binder/include/binder/RpcConnection.h
@@ -61,6 +61,27 @@
*/
[[nodiscard]] bool addUnixDomainClient(const char* path);
+#ifdef __BIONIC__
+ /**
+ * Creates an RPC server at the current port.
+ */
+ [[nodiscard]] bool setupVsockServer(unsigned int port);
+
+ /**
+ * Connects to an RPC server at the CVD & port.
+ */
+ [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port);
+#endif // __BIONIC__
+
+ /**
+ * For debugging!
+ *
+ * Sets up an empty socket. All queries to this socket which require a
+ * response will never be satisfied. All data sent here will be
+ * unceremoniously cast down the bottomless pit, /dev/null.
+ */
+ [[nodiscard]] bool addNullDebuggingClient();
+
/**
* Query the other side of the connection for the root object hosted by that
* process's RpcServer (if one exists)
@@ -85,11 +106,22 @@
// internal only
const std::unique_ptr<RpcState>& state() { return mState; }
+ class SocketAddress {
+ public:
+ virtual ~SocketAddress();
+ virtual std::string toString() const = 0;
+ virtual const sockaddr* addr() const = 0;
+ virtual size_t addrSize() const = 0;
+ };
+
private:
+ friend sp<RpcConnection>;
RpcConnection();
- void addServer(base::unique_fd&& fd);
+ bool setupSocketServer(const SocketAddress& address);
+ bool addSocketClient(const SocketAddress& address);
void addClient(base::unique_fd&& fd);
+ void assignServerToThisThread(base::unique_fd&& fd);
struct ConnectionSocket : public RefBase {
base::unique_fd fd;
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index a2c2aee..d29b651 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -72,6 +72,7 @@
~RpcServer();
private:
+ friend sp<RpcServer>;
RpcServer();
bool mAgreedExperimental = false;
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index a09e587..f4bfac8 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -54,12 +54,37 @@
// Given a binder interface at a certain stability, there may be some
// requirements associated with that higher stability level. For instance, a
// VINTF stability binder is required to be in the VINTF manifest. This API
- // can be called to use that same interface within a partition.
- static void forceDowngradeCompilationUnit(const sp<IBinder>& binder);
+ // can be called to use that same interface within the local partition.
+ static void forceDowngradeToLocalStability(const sp<IBinder>& binder);
// WARNING: Below APIs are only ever expected to be called by auto-generated code.
// Instead of calling them, you should set the stability of a .aidl interface
+ // WARNING: The only client of
+ // - forceDowngradeToSystemStability() and;
+ // - korceDowngradeToVendorStability()
+ // should be AIBinder_forceDowngradeToLocalStability().
+ //
+ // getLocalLevel() in libbinder returns Level::SYSTEM when called
+ // from libbinder_ndk (even on vendor partition). So we explicitly provide
+ // these methods for use by the NDK API:
+ // AIBinder_forceDowngradeToLocalStability().
+ //
+ // This allows correctly downgrading the binder's stability to either system/vendor,
+ // depending on the partition.
+
+ // Given a binder interface at a certain stability, there may be some
+ // requirements associated with that higher stability level. For instance, a
+ // VINTF stability binder is required to be in the VINTF manifest. This API
+ // can be called to use that same interface within the vendor partition.
+ static void forceDowngradeToVendorStability(const sp<IBinder>& binder);
+
+ // Given a binder interface at a certain stability, there may be some
+ // requirements associated with that higher stability level. For instance, a
+ // VINTF stability binder is required to be in the VINTF manifest. This API
+ // can be called to use that same interface within the system partition.
+ static void forceDowngradeToSystemStability(const sp<IBinder>& binder);
+
// WARNING: This is only ever expected to be called by auto-generated code. You likely want to
// change or modify the stability class of the interface you are using.
// This must be called as soon as the binder in question is constructed. No thread safety
@@ -146,6 +171,9 @@
// returns the stability according to how this was built
static Level getLocalLevel();
+ // Downgrades binder stability to the specified level.
+ static void forceDowngradeToStability(const sp<IBinder>& binder, Level level);
+
enum {
REPR_NONE = 0,
REPR_LOG = 1,
diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h
index c30ae01..aaafa36 100644
--- a/libs/binder/include/binder/Status.h
+++ b/libs/binder/include/binder/Status.h
@@ -91,6 +91,9 @@
static Status fromExceptionCode(int32_t exceptionCode,
const char* message);
+ // warning: this is still considered an error if it is constructed with a
+ // zero value error code. Please use Status::ok() instead and avoid zero
+ // error codes
static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);
static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
const String8& message);
diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include_activitymanager/binder/ActivityManager.h
similarity index 100%
rename from libs/binder/include/binder/ActivityManager.h
rename to libs/binder/include_activitymanager/binder/ActivityManager.h
diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include_activitymanager/binder/IActivityManager.h
similarity index 99%
rename from libs/binder/include/binder/IActivityManager.h
rename to libs/binder/include_activitymanager/binder/IActivityManager.h
index fde56a0..e3b5e43 100644
--- a/libs/binder/include/binder/IActivityManager.h
+++ b/libs/binder/include_activitymanager/binder/IActivityManager.h
@@ -18,8 +18,8 @@
#ifndef __ANDROID_VNDK__
-#include <binder/IInterface.h>
#include <binder/IUidObserver.h>
+#include <binder/IInterface.h>
namespace android {
diff --git a/libs/binder/include/binder/IUidObserver.h b/libs/binder/include_activitymanager/binder/IUidObserver.h
similarity index 100%
rename from libs/binder/include/binder/IUidObserver.h
rename to libs/binder/include_activitymanager/binder/IUidObserver.h
diff --git a/libs/binder/include/binder/IBatteryStats.h b/libs/binder/include_batterystats/batterystats/IBatteryStats.h
similarity index 100%
rename from libs/binder/include/binder/IBatteryStats.h
rename to libs/binder/include_batterystats/batterystats/IBatteryStats.h
diff --git a/libs/binder/include/binder/IProcessInfoService.h b/libs/binder/include_processinfo/processinfo/IProcessInfoService.h
similarity index 100%
rename from libs/binder/include/binder/IProcessInfoService.h
rename to libs/binder/include_processinfo/processinfo/IProcessInfoService.h
diff --git a/libs/binder/include/binder/ProcessInfoService.h b/libs/binder/include_processinfo/processinfo/ProcessInfoService.h
similarity index 98%
rename from libs/binder/include/binder/ProcessInfoService.h
rename to libs/binder/include_processinfo/processinfo/ProcessInfoService.h
index 6b3b5ce..978856d 100644
--- a/libs/binder/include/binder/ProcessInfoService.h
+++ b/libs/binder/include_processinfo/processinfo/ProcessInfoService.h
@@ -18,7 +18,7 @@
#ifndef __ANDROID_VNDK__
-#include <binder/IProcessInfoService.h>
+#include <processinfo/IProcessInfoService.h>
#include <utils/Errors.h>
#include <utils/Singleton.h>
#include <sys/types.h>
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 0f59de4..883403a 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -363,7 +363,8 @@
}
void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
- CHECK(who == mWho);
+ CHECK(who == mWho) << who.unsafe_get() << "(" << who.get_refs() << ") vs " << mWho.unsafe_get()
+ << " (" << mWho.get_refs() << ")";
mOnDied(mCookie);
@@ -598,6 +599,8 @@
}
*in = new AParcel(binder);
+ (*in)->get()->markForBinder(binder->getBinder());
+
status_t status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
binder_status_t ret = PruneStatusT(status);
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 8941e49..9e2050b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -36,6 +36,9 @@
__BEGIN_DECLS
+/**
+ * Flags for AIBinder_transact.
+ */
typedef uint32_t binder_flags_t;
enum {
/**
@@ -47,7 +50,10 @@
FLAG_ONEWAY = 0x01,
};
-// Also see IBinder.h in libbinder
+/**
+ * Codes for AIBinder_transact. This defines the range of codes available for
+ * usage. Other codes are used or reserved by the Android system.
+ */
typedef uint32_t transaction_code_t;
enum {
/**
@@ -167,7 +173,7 @@
* Available since API level 29.
*
* \param interfaceDescriptor this is a unique identifier for the class. This is used internally for
- * sanity checks on transactions.
+ * validity checks on transactions. This should be utf-8.
* \param onCreate see AIBinder_Class_onCreate.
* \param onDestroy see AIBinder_Class_onDestroy.
* \param onTransact see AIBinder_Class_onTransact.
@@ -202,7 +208,8 @@
*
* Available since API level 29.
*
- * \param dump function to call when an instance of this binder class is being dumped.
+ * \param clazz class which should use this dump function
+ * \param onDump function to call when an instance of this binder class is being dumped.
*/
void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29);
@@ -638,7 +645,9 @@
*
* \return the class descriptor string. This pointer will never be null; a
* descriptor is required to define a class. The pointer is owned by the class
- * and will remain valid as long as the class does.
+ * and will remain valid as long as the class does. For a local class, this will
+ * be the same value (not necessarily pointer equal) as is passed into
+ * AIBinder_Class_define. Format is utf-8.
*/
const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) __INTRODUCED_IN(31);
@@ -662,7 +671,7 @@
*
* \return whether "lhs < rhs" is true
*/
-bool AIBinder_lt(const AIBinder* lhs, const AIBinder* rhs);
+bool AIBinder_lt(const AIBinder* lhs, const AIBinder* rhs) __INTRODUCED_IN(31);
/**
* Clone an AIBinder_Weak. Useful because even if a weak binder promotes to a
@@ -676,7 +685,7 @@
* \return clone of the input parameter. This must be deleted with
* AIBinder_Weak_delete. Null if weak input parameter is also null.
*/
-AIBinder_Weak* AIBinder_Weak_clone(const AIBinder_Weak* weak);
+AIBinder_Weak* AIBinder_Weak_clone(const AIBinder_Weak* weak) __INTRODUCED_IN(31);
/**
* Whether AIBinder_Weak is less than another.
@@ -711,7 +720,7 @@
*
* \return whether "lhs < rhs" is true
*/
-bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs);
+bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs) __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index b4dc08a..6f1fdfc 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -189,7 +189,7 @@
*
* Available since API level 29.
*
- * \param a low-level error to associate with this status object.
+ * \param status a low-level error to associate with this status object.
*
* \return a newly constructed status object that the caller owns.
*/
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 0668472..5516914 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -26,7 +26,7 @@
* This registers the service with the default service manager under this instance name. This does
* not take ownership of binder.
*
- * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * WARNING: when using this API across an APEX boundary, do not use with unstable
* AIDL services. TODO(b/139325195)
*
* \param binder object to register globally with the service manager.
@@ -42,7 +42,7 @@
* service is not available This also implicitly calls AIBinder_incStrong (so the caller of this
* function is responsible for calling AIBinder_decStrong).
*
- * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * WARNING: when using this API across an APEX boundary, do not use with unstable
* AIDL services. TODO(b/139325195)
*
* \param instance identifier of the service used to lookup the service.
@@ -54,7 +54,7 @@
* it. This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
* for calling AIBinder_decStrong).
*
- * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * WARNING: when using this API across an APEX boundary, do not use with unstable
* AIDL services. TODO(b/139325195)
*
* \param instance identifier of the service used to lookup the service.
@@ -87,7 +87,7 @@
* This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
* for calling AIBinder_decStrong).
*
- * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * WARNING: when using this API across an APEX boundary, do not use with unstable
* AIDL services. TODO(b/139325195)
*
* \param instance identifier of the service used to lookup the service.
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index f5e8bf6..f113ba8 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -30,7 +30,7 @@
FLAG_PRIVATE_VENDOR = 0x10000000,
};
-#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID_VENDOR__)
enum {
FLAG_PRIVATE_LOCAL = FLAG_PRIVATE_VENDOR,
@@ -45,7 +45,19 @@
AIBinder_markVendorStability(binder);
}
-#else // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+/**
+ * Given a binder interface at a certain stability, there may be some
+ * requirements associated with that higher stability level. For instance, a
+ * VINTF stability binder is required to be in the VINTF manifest. This API
+ * can be called to use that same interface within the vendor partition.
+ */
+void AIBinder_forceDowngradeToVendorStability(AIBinder* binder);
+
+static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) {
+ AIBinder_forceDowngradeToVendorStability(binder);
+}
+
+#else // defined(__ANDROID_VENDOR__)
enum {
FLAG_PRIVATE_LOCAL = 0,
@@ -62,9 +74,27 @@
AIBinder_markSystemStability(binder);
}
-#endif // defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+/**
+ * Given a binder interface at a certain stability, there may be some
+ * requirements associated with that higher stability level. For instance, a
+ * VINTF stability binder is required to be in the VINTF manifest. This API
+ * can be called to use that same interface within the system partition.
+ */
+void AIBinder_forceDowngradeToSystemStability(AIBinder* binder);
+
+static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) {
+ AIBinder_forceDowngradeToSystemStability(binder);
+}
+
+#endif // defined(__ANDROID_VENDOR__)
/**
+ * WARNING: this is not expected to be used manually. When the build system has
+ * versioned checks in place for an interface that prevent it being changed year
+ * over year (specifically like those for @VintfStability stable AIDL
+ * interfaces), this could be called. Calling this without this or equivalent
+ * infrastructure will lead to de facto frozen APIs or GSI test failures.
+ *
* This interface has system<->vendor stability
*/
void AIBinder_markVintfStability(AIBinder* binder);
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index f1db653..67c85b6 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -127,6 +127,9 @@
AServiceManager_tryUnregister; # llndk
AServiceManager_reRegister; # llndk
+ AIBinder_forceDowngradeToSystemStability; # apex
+ AIBinder_forceDowngradeToVendorStability; # llndk
+
AIBinder_Class_getDescriptor;
AIBinder_Weak_clone;
AIBinder_Weak_lt;
diff --git a/libs/binder/ndk/parcel_internal.h b/libs/binder/ndk/parcel_internal.h
index 6b7295e..b4f6358 100644
--- a/libs/binder/ndk/parcel_internal.h
+++ b/libs/binder/ndk/parcel_internal.h
@@ -27,9 +27,8 @@
const ::android::Parcel* get() const { return mParcel; }
::android::Parcel* get() { return mParcel; }
- explicit AParcel(const AIBinder* binder)
- : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
- AParcel(const AIBinder* binder, ::android::Parcel* parcel, bool owns)
+ explicit AParcel(AIBinder* binder) : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
+ AParcel(AIBinder* binder, ::android::Parcel* parcel, bool owns)
: mBinder(binder), mParcel(parcel), mOwns(owns) {}
~AParcel() {
@@ -38,7 +37,7 @@
}
}
- static const AParcel readOnly(const AIBinder* binder, const ::android::Parcel* parcel) {
+ static const AParcel readOnly(AIBinder* binder, const ::android::Parcel* parcel) {
return AParcel(binder, const_cast<::android::Parcel*>(parcel), false);
}
diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp
index a5b3ece..7eafb9c 100644
--- a/libs/binder/ndk/stability.cpp
+++ b/libs/binder/ndk/stability.cpp
@@ -31,7 +31,7 @@
#error libbinder_ndk should only be built in a system context
#endif
-// explicit extern because symbol is only declared in header when __ANDROID_VNDK__
+// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__
extern "C" void AIBinder_markVendorStability(AIBinder* binder) {
Stability::markVndk(binder->getBinder().get());
}
@@ -43,3 +43,12 @@
void AIBinder_markVintfStability(AIBinder* binder) {
Stability::markVintf(binder->getBinder().get());
}
+
+// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__
+extern "C" void AIBinder_forceDowngradeToVendorStability(AIBinder* binder) {
+ Stability::forceDowngradeToVendorStability(binder->getBinder());
+}
+
+void AIBinder_forceDowngradeToSystemStability(AIBinder* binder) {
+ Stability::forceDowngradeToSystemStability(binder->getBinder());
+}
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index e12a429..57c9013 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -65,15 +65,15 @@
// rustified
"--constified-enum", "android::c_interface::consts::.*",
- "--whitelist-type", "android::c_interface::.*",
- "--whitelist-type", "AStatus",
- "--whitelist-type", "AIBinder_Class",
- "--whitelist-type", "AIBinder",
- "--whitelist-type", "AIBinder_Weak",
- "--whitelist-type", "AIBinder_DeathRecipient",
- "--whitelist-type", "AParcel",
- "--whitelist-type", "binder_status_t",
- "--whitelist-function", ".*",
+ "--allowlist-type", "android::c_interface::.*",
+ "--allowlist-type", "AStatus",
+ "--allowlist-type", "AIBinder_Class",
+ "--allowlist-type", "AIBinder",
+ "--allowlist-type", "AIBinder_Weak",
+ "--allowlist-type", "AIBinder_DeathRecipient",
+ "--allowlist-type", "AParcel",
+ "--allowlist-type", "binder_status_t",
+ "--allowlist-function", ".*",
],
shared_libs: [
"libbinder_ndk",
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 0bf76c6..607860f 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -114,8 +114,8 @@
source_stem: "bindings",
cpp_std: "gnu++17",
bindgen_flags: [
- "--whitelist-type", "Transaction",
- "--whitelist-var", "TESTDATA_.*",
+ "--allowlist-type", "Transaction",
+ "--allowlist-var", "TESTDATA_.*",
],
shared_libs: [
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index a44cddf..f303b7c 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -104,26 +104,74 @@
require_root: true,
}
-cc_test {
- name: "binderRpcTest",
- defaults: ["binder_test_defaults"],
-
+aidl_interface {
+ name: "binderRpcTestIface",
+ host_supported: true,
+ unstable: true,
srcs: [
"IBinderRpcSession.aidl",
"IBinderRpcTest.aidl",
+ ],
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
+}
+
+cc_test {
+ name: "binderRpcTest",
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ defaults: [
+ "binder_test_defaults",
+ "libbinder_ndk_host_user",
+ ],
+
+ srcs: [
"binderRpcTest.cpp",
],
shared_libs: [
"libbinder",
+ "libbinder_ndk",
"libbase",
"libutils",
"libcutils",
"liblog",
],
+ static_libs: [
+ "binderRpcTestIface-cpp",
+ "binderRpcTestIface-ndk_platform",
+ ],
test_suites: ["general-tests"],
require_root: true,
}
+cc_benchmark {
+ name: "binderRpcBenchmark",
+ defaults: ["binder_test_defaults"],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ srcs: [
+ "binderRpcBenchmark.cpp",
+ "IBinderRpcBenchmark.aidl",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+}
+
cc_test {
name: "binderThroughputTest",
defaults: ["binder_test_defaults"],
@@ -210,6 +258,11 @@
srcs: [
"IBinderStabilityTest.aidl",
],
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
}
cc_test {
diff --git a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/tests/IBinderRpcBenchmark.aidl
similarity index 69%
copy from libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
copy to libs/binder/tests/IBinderRpcBenchmark.aidl
index b92a6a9..1457422 100644
--- a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
+++ b/libs/binder/tests/IBinderRpcBenchmark.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,11 +14,7 @@
* limitations under the License.
*/
-#pragma once
-
-#include <binder/Parcel.h>
-#include <fuzzer/FuzzedDataProvider.h>
-
-namespace android {
-void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider);
-} // namespace android
+interface IBinderRpcBenchmark {
+ @utf8InCpp String repeatString(@utf8InCpp String str);
+ IBinder repeatBinder(IBinder binder);
+}
diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp
new file mode 100644
index 0000000..7c82226
--- /dev/null
+++ b/libs/binder/tests/binderRpcBenchmark.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 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 <BnBinderRpcBenchmark.h>
+#include <android-base/logging.h>
+#include <benchmark/benchmark.h>
+#include <binder/Binder.h>
+#include <binder/RpcConnection.h>
+#include <binder/RpcServer.h>
+
+#include <thread>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+using android::BBinder;
+using android::IBinder;
+using android::interface_cast;
+using android::OK;
+using android::RpcConnection;
+using android::RpcServer;
+using android::sp;
+using android::binder::Status;
+
+class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
+ Status repeatString(const std::string& str, std::string* out) override {
+ *out = str;
+ return Status::ok();
+ }
+ Status repeatBinder(const sp<IBinder>& str, sp<IBinder>* out) override {
+ *out = str;
+ return Status::ok();
+ }
+};
+
+static sp<RpcConnection> gConnection = RpcConnection::make();
+
+void BM_getRootObject(benchmark::State& state) {
+ while (state.KeepRunning()) {
+ CHECK(gConnection->getRootObject() != nullptr);
+ }
+}
+BENCHMARK(BM_getRootObject);
+
+void BM_pingTransaction(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+
+ while (state.KeepRunning()) {
+ CHECK_EQ(OK, binder->pingBinder());
+ }
+}
+BENCHMARK(BM_pingTransaction);
+
+void BM_repeatString(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+ sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+ CHECK(iface != nullptr);
+
+ // Googlers might see go/another-look-at-aidl-hidl-perf
+ //
+ // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
+ // transactions were less than one page in size (system wide during a test
+ // involving media and camera). This is why this diverges from
+ // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
+ // this data on continuous integration. Here we are testing sending a
+ // transaction of twice this size. In other cases, we should focus on
+ // benchmarks of particular usecases. If individual binder transactions like
+ // the ones tested here are fast, then Android performance will be dominated
+ // by how many binder calls work together (and by factors like the scheduler,
+ // thermal throttling, core choice, etc..).
+ std::string str = std::string(getpagesize() * 2, 'a');
+ CHECK_EQ(str.size(), getpagesize() * 2);
+
+ while (state.KeepRunning()) {
+ std::string out;
+ Status ret = iface->repeatString(str, &out);
+ CHECK(ret.isOk()) << ret;
+ }
+}
+BENCHMARK(BM_repeatString);
+
+void BM_repeatBinder(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+ sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+ CHECK(iface != nullptr);
+
+ while (state.KeepRunning()) {
+ // force creation of a new address
+ sp<IBinder> binder = sp<BBinder>::make();
+
+ sp<IBinder> out;
+ Status ret = iface->repeatBinder(binder, &out);
+ CHECK(ret.isOk()) << ret;
+ }
+}
+BENCHMARK(BM_repeatBinder);
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
+
+ std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
+ (void)unlink(addr.c_str());
+
+ std::thread([addr]() {
+ sp<RpcServer> server = RpcServer::make();
+ server->setRootObject(sp<MyBinderRpcBenchmark>::make());
+
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+
+ sp<RpcConnection> connection = server->addClientConnection();
+ CHECK(connection->setupUnixDomainServer(addr.c_str()));
+
+ connection->join();
+ }).detach();
+
+ for (size_t tries = 0; tries < 5; tries++) {
+ usleep(10000);
+ if (gConnection->addUnixDomainClient(addr.c_str())) goto success;
+ }
+ LOG(FATAL) << "Could not connect.";
+success:
+
+ ::benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 6fa5333..3340293 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -14,17 +14,12 @@
* limitations under the License.
*/
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <cstdlib>
-#include <iostream>
-#include <thread>
-
#include <BnBinderRpcSession.h>
#include <BnBinderRpcTest.h>
+#include <aidl/IBinderRpcTest.h>
#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_libbinder.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
#include <binder/IServiceManager.h>
@@ -33,10 +28,29 @@
#include <binder/RpcServer.h>
#include <gtest/gtest.h>
+#include <chrono>
+#include <cstdlib>
+#include <iostream>
+#include <thread>
+
+#ifdef __BIONIC__
+#include <linux/vm_sockets.h>
+#endif //__BIONIC__
+
+#include <sys/prctl.h>
+#include <unistd.h>
+
#include "../RpcState.h" // for debugging
namespace android {
+TEST(BinderRpcParcel, EntireParcelFormatted) {
+ Parcel p;
+ p.writeInt32(3);
+
+ EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "");
+}
+
using android::binder::Status;
#define EXPECT_OK(status) \
@@ -185,8 +199,8 @@
static std::string allocateSocketAddress() {
static size_t id = 0;
-
- return "/dev/binderRpcTest_" + std::to_string(id++);
+ std::string temp = getenv("TMPDIR") ?: "/tmp";
+ return temp + "/binderRpcTest_" + std::to_string(id++);
};
struct ProcessConnection {
@@ -214,58 +228,6 @@
}
};
-// This creates a new process serving an interface on a certain number of
-// threads.
-ProcessConnection createRpcTestSocketServerProcess(
- size_t numThreads,
- const std::function<void(const sp<RpcServer>&, const sp<RpcConnection>&)>& configure) {
- CHECK_GT(numThreads, 0);
-
- std::string addr = allocateSocketAddress();
- unlink(addr.c_str());
-
- auto ret = ProcessConnection{
- .host = Process([&] {
- sp<RpcServer> server = RpcServer::make();
-
- server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
-
- // server supporting one client on one socket
- sp<RpcConnection> connection = server->addClientConnection();
- CHECK(connection->setupUnixDomainServer(addr.c_str())) << addr;
-
- configure(server, connection);
-
- // accept 'numThreads' connections
- std::vector<std::thread> pool;
- for (size_t i = 0; i + 1 < numThreads; i++) {
- pool.push_back(std::thread([=] { connection->join(); }));
- }
- connection->join();
- for (auto& t : pool) t.join();
- }),
- .connection = RpcConnection::make(),
- };
-
- // wait up to 1s for sockets to be created
- constexpr useconds_t kMaxWaitUs = 1000000;
- constexpr useconds_t kWaitDivision = 100;
- for (size_t i = 0; i < kWaitDivision && 0 != access(addr.c_str(), F_OK); i++) {
- usleep(kMaxWaitUs / kWaitDivision);
- }
-
- // create remainder of connections
- for (size_t i = 0; i < numThreads; i++) {
- // Connection refused sometimes after file created but before listening.
- CHECK(ret.connection->addUnixDomainClient(addr.c_str()) ||
- (usleep(10000), ret.connection->addUnixDomainClient(addr.c_str())))
- << i;
- }
-
- ret.rootBinder = ret.connection->getRootObject();
- return ret;
-}
-
// Process connection where the process hosts IBinderRpcTest, the server used
// for most testing here
struct BinderRpcTestProcessConnection {
@@ -290,26 +252,122 @@
}
};
-BinderRpcTestProcessConnection createRpcTestSocketServerProcess(size_t numThreads) {
- BinderRpcTestProcessConnection ret{
- .proc = createRpcTestSocketServerProcess(numThreads,
- [&](const sp<RpcServer>& server,
- const sp<RpcConnection>& connection) {
- sp<MyBinderRpcTest> service =
- new MyBinderRpcTest;
- server->setRootObject(service);
- service->connection =
- connection; // for testing only
- }),
- };
-
- ret.rootBinder = ret.proc.rootBinder;
- ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
-
- return ret;
+enum class SocketType {
+ UNIX,
+#ifdef __BIONIC__
+ VSOCK,
+#endif // __BIONIC__
+};
+static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
+ switch (info.param) {
+ case SocketType::UNIX:
+ return "unix_domain_socket";
+#ifdef __BIONIC__
+ case SocketType::VSOCK:
+ return "vm_socket";
+#endif // __BIONIC__
+ default:
+ LOG_ALWAYS_FATAL("Unknown socket type");
+ return "";
+ }
}
+class BinderRpc : public ::testing::TestWithParam<SocketType> {
+public:
+ // This creates a new process serving an interface on a certain number of
+ // threads.
+ ProcessConnection createRpcTestSocketServerProcess(
+ size_t numThreads,
+ const std::function<void(const sp<RpcServer>&, const sp<RpcConnection>&)>& configure) {
+ CHECK_GT(numThreads, 0);
-TEST(BinderRpc, RootObjectIsNull) {
+ SocketType socketType = GetParam();
+
+ std::string addr = allocateSocketAddress();
+ unlink(addr.c_str());
+ static unsigned int port = 3456;
+ port++;
+
+ auto ret = ProcessConnection{
+ .host = Process([&] {
+ sp<RpcServer> server = RpcServer::make();
+
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+
+ // server supporting one client on one socket
+ sp<RpcConnection> connection = server->addClientConnection();
+
+ switch (socketType) {
+ case SocketType::UNIX:
+ CHECK(connection->setupUnixDomainServer(addr.c_str())) << addr;
+ break;
+#ifdef __BIONIC__
+ case SocketType::VSOCK:
+ CHECK(connection->setupVsockServer(port));
+ break;
+#endif // __BIONIC__
+ default:
+ LOG_ALWAYS_FATAL("Unknown socket type");
+ }
+
+ configure(server, connection);
+
+ // accept 'numThreads' connections
+ std::vector<std::thread> pool;
+ for (size_t i = 0; i + 1 < numThreads; i++) {
+ pool.push_back(std::thread([=] { connection->join(); }));
+ }
+ connection->join();
+ for (auto& t : pool) t.join();
+ }),
+ .connection = RpcConnection::make(),
+ };
+
+ // create remainder of connections
+ for (size_t i = 0; i < numThreads; i++) {
+ for (size_t tries = 0; tries < 5; tries++) {
+ usleep(10000);
+ switch (socketType) {
+ case SocketType::UNIX:
+ if (ret.connection->addUnixDomainClient(addr.c_str())) goto success;
+ break;
+#ifdef __BIONIC__
+ case SocketType::VSOCK:
+ if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
+ break;
+#endif // __BIONIC__
+ default:
+ LOG_ALWAYS_FATAL("Unknown socket type");
+ }
+ }
+ LOG_ALWAYS_FATAL("Could not connect");
+ success:;
+ }
+
+ ret.rootBinder = ret.connection->getRootObject();
+ return ret;
+ }
+
+ BinderRpcTestProcessConnection createRpcTestSocketServerProcess(size_t numThreads) {
+ BinderRpcTestProcessConnection ret{
+ .proc = createRpcTestSocketServerProcess(numThreads,
+ [&](const sp<RpcServer>& server,
+ const sp<RpcConnection>& connection) {
+ sp<MyBinderRpcTest> service =
+ new MyBinderRpcTest;
+ server->setRootObject(service);
+ service->connection =
+ connection; // for testing only
+ }),
+ };
+
+ ret.rootBinder = ret.proc.rootBinder;
+ ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
+
+ return ret;
+ }
+};
+
+TEST_P(BinderRpc, RootObjectIsNull) {
auto proc = createRpcTestSocketServerProcess(1,
[](const sp<RpcServer>& server,
const sp<RpcConnection>&) {
@@ -324,20 +382,39 @@
EXPECT_EQ(nullptr, proc.connection->getRootObject());
}
-TEST(BinderRpc, Ping) {
+TEST_P(BinderRpc, Ping) {
auto proc = createRpcTestSocketServerProcess(1);
ASSERT_NE(proc.rootBinder, nullptr);
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
}
-TEST(BinderRpc, TransactionsMustBeMarkedRpc) {
+TEST_P(BinderRpc, GetInterfaceDescriptor) {
+ auto proc = createRpcTestSocketServerProcess(1);
+ ASSERT_NE(proc.rootBinder, nullptr);
+ EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor());
+}
+
+TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
auto proc = createRpcTestSocketServerProcess(1);
Parcel data;
Parcel reply;
EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
}
-TEST(BinderRpc, UnknownTransaction) {
+TEST_P(BinderRpc, AppendSeparateFormats) {
+ auto proc = createRpcTestSocketServerProcess(1);
+
+ Parcel p1;
+ p1.markForBinder(proc.rootBinder);
+ p1.writeInt32(3);
+
+ Parcel p2;
+
+ EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize()));
+ EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize()));
+}
+
+TEST_P(BinderRpc, UnknownTransaction) {
auto proc = createRpcTestSocketServerProcess(1);
Parcel data;
data.markForBinder(proc.rootBinder);
@@ -345,19 +422,19 @@
EXPECT_EQ(UNKNOWN_TRANSACTION, proc.rootBinder->transact(1337, data, &reply, 0));
}
-TEST(BinderRpc, SendSomethingOneway) {
+TEST_P(BinderRpc, SendSomethingOneway) {
auto proc = createRpcTestSocketServerProcess(1);
EXPECT_OK(proc.rootIface->sendString("asdf"));
}
-TEST(BinderRpc, SendAndGetResultBack) {
+TEST_P(BinderRpc, SendAndGetResultBack) {
auto proc = createRpcTestSocketServerProcess(1);
std::string doubled;
EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
EXPECT_EQ("cool cool ", doubled);
}
-TEST(BinderRpc, SendAndGetResultBackBig) {
+TEST_P(BinderRpc, SendAndGetResultBackBig) {
auto proc = createRpcTestSocketServerProcess(1);
std::string single = std::string(1024, 'a');
std::string doubled;
@@ -365,7 +442,7 @@
EXPECT_EQ(single + single, doubled);
}
-TEST(BinderRpc, CallMeBack) {
+TEST_P(BinderRpc, CallMeBack) {
auto proc = createRpcTestSocketServerProcess(1);
int32_t pingResult;
@@ -375,7 +452,7 @@
EXPECT_EQ(0, MyBinderRpcSession::gNum);
}
-TEST(BinderRpc, RepeatBinder) {
+TEST_P(BinderRpc, RepeatBinder) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> inBinder = new MyBinderRpcSession("foo");
@@ -397,7 +474,7 @@
EXPECT_EQ(0, MyBinderRpcSession::gNum);
}
-TEST(BinderRpc, RepeatTheirBinder) {
+TEST_P(BinderRpc, RepeatTheirBinder) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinderRpcSession> session;
@@ -421,7 +498,7 @@
EXPECT_EQ(nullptr, weak.promote());
}
-TEST(BinderRpc, RepeatBinderNull) {
+TEST_P(BinderRpc, RepeatBinderNull) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> outBinder;
@@ -429,7 +506,7 @@
EXPECT_EQ(nullptr, outBinder);
}
-TEST(BinderRpc, HoldBinder) {
+TEST_P(BinderRpc, HoldBinder) {
auto proc = createRpcTestSocketServerProcess(1);
IBinder* ptr = nullptr;
@@ -455,7 +532,7 @@
// These are behavioral differences form regular binder, where certain usecases
// aren't supported.
-TEST(BinderRpc, CannotMixBindersBetweenUnrelatedSocketConnections) {
+TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketConnections) {
auto proc1 = createRpcTestSocketServerProcess(1);
auto proc2 = createRpcTestSocketServerProcess(1);
@@ -464,7 +541,7 @@
proc1.rootIface->repeatBinder(proc2.rootBinder, &outBinder).transactionError());
}
-TEST(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
+TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
@@ -473,7 +550,7 @@
proc.rootIface->repeatBinder(someRealBinder, &outBinder).transactionError());
}
-TEST(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
+TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
auto proc = createRpcTestSocketServerProcess(1);
// for historical reasons, IServiceManager interface only returns the
@@ -484,7 +561,7 @@
// END TESTS FOR LIMITATIONS OF SOCKET BINDER
-TEST(BinderRpc, RepeatRootObject) {
+TEST_P(BinderRpc, RepeatRootObject) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> outBinder;
@@ -492,7 +569,7 @@
EXPECT_EQ(proc.rootBinder, outBinder);
}
-TEST(BinderRpc, NestedTransactions) {
+TEST_P(BinderRpc, NestedTransactions) {
auto proc = createRpcTestSocketServerProcess(1);
auto nastyNester = sp<MyBinderRpcTest>::make();
@@ -503,7 +580,7 @@
EXPECT_EQ(nullptr, weak.promote());
}
-TEST(BinderRpc, SameBinderEquality) {
+TEST_P(BinderRpc, SameBinderEquality) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> a;
@@ -515,7 +592,7 @@
EXPECT_EQ(a, b);
}
-TEST(BinderRpc, SameBinderEqualityWeak) {
+TEST_P(BinderRpc, SameBinderEqualityWeak) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinder> a;
@@ -547,7 +624,7 @@
EXPECT_EQ(expected, session); \
} while (false)
-TEST(BinderRpc, SingleSession) {
+TEST_P(BinderRpc, SingleSession) {
auto proc = createRpcTestSocketServerProcess(1);
sp<IBinderRpcSession> session;
@@ -561,7 +638,7 @@
expectSessions(0, proc.rootIface);
}
-TEST(BinderRpc, ManySessions) {
+TEST_P(BinderRpc, ManySessions) {
auto proc = createRpcTestSocketServerProcess(1);
std::vector<sp<IBinderRpcSession>> sessions;
@@ -595,7 +672,7 @@
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}
-TEST(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
+TEST_P(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
constexpr size_t kNumThreads = 10;
auto proc = createRpcTestSocketServerProcess(kNumThreads);
@@ -627,7 +704,7 @@
for (auto& t : ts) t.join();
}
-TEST(BinderRpc, ThreadPoolOverSaturated) {
+TEST_P(BinderRpc, ThreadPoolOverSaturated) {
constexpr size_t kNumThreads = 10;
constexpr size_t kNumCalls = kNumThreads + 3;
constexpr size_t kSleepMs = 500;
@@ -651,7 +728,7 @@
EXPECT_LE(epochMsAfter, epochMsBefore + 3 * kSleepMs);
}
-TEST(BinderRpc, ThreadingStressTest) {
+TEST_P(BinderRpc, ThreadingStressTest) {
constexpr size_t kNumClientThreads = 10;
constexpr size_t kNumServerThreads = 10;
constexpr size_t kNumCalls = 100;
@@ -672,7 +749,7 @@
for (auto& t : threads) t.join();
}
-TEST(BinderRpc, OnewayCallDoesNotWait) {
+TEST_P(BinderRpc, OnewayCallDoesNotWait) {
constexpr size_t kReallyLongTimeMs = 100;
constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
@@ -687,7 +764,7 @@
EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
}
-TEST(BinderRpc, OnewayCallQueueing) {
+TEST_P(BinderRpc, OnewayCallQueueing) {
constexpr size_t kNumSleeps = 10;
constexpr size_t kNumExtraServerThreads = 4;
constexpr size_t kSleepMs = 50;
@@ -711,10 +788,7 @@
EXPECT_GT(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);
}
-TEST(BinderRpc, Die) {
- // TODO(b/183141167): handle this in library
- signal(SIGPIPE, SIG_IGN);
-
+TEST_P(BinderRpc, Die) {
for (bool doDeathCleanup : {true, false}) {
auto proc = createRpcTestSocketServerProcess(1);
@@ -733,6 +807,30 @@
}
}
+TEST_P(BinderRpc, WorksWithLibbinderNdkPing) {
+ auto proc = createRpcTestSocketServerProcess(1);
+
+ ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
+ ASSERT_NE(binder, nullptr);
+
+ ASSERT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
+}
+
+TEST_P(BinderRpc, WorksWithLibbinderNdkUserTransaction) {
+ auto proc = createRpcTestSocketServerProcess(1);
+
+ ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
+ ASSERT_NE(binder, nullptr);
+
+ auto ndkBinder = aidl::IBinderRpcTest::fromBinder(binder);
+ ASSERT_NE(ndkBinder, nullptr);
+
+ std::string out;
+ ndk::ScopedAStatus status = ndkBinder->doubleString("aoeu", &out);
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
+ ASSERT_EQ("aoeuaoeu", out);
+}
+
ssize_t countFds() {
DIR* dir = opendir("/proc/self/fd/");
if (dir == nullptr) return -1;
@@ -743,7 +841,7 @@
return ret;
}
-TEST(BinderRpc, Fds) {
+TEST_P(BinderRpc, Fds) {
ssize_t beforeFds = countFds();
ASSERT_GE(beforeFds, 0);
{
@@ -753,10 +851,19 @@
ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
}
-extern "C" int main(int argc, char** argv) {
+INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
+ ::testing::Values(SocketType::UNIX
+#ifdef __BIONIC__
+ ,
+ SocketType::VSOCK
+#endif // __BIONIC__
+ ),
+ PrintSocketType);
+
+} // namespace android
+
+int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter);
return RUN_ALL_TESTS();
}
-
-} // namespace android
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index ffb3ef2..c857d62 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -226,7 +226,7 @@
IncrementNativeHandle,
IncrementNoCopyNoMove,
IncrementParcelableVector,
- ToUpper,
+ DoubleString,
CallMeBack,
IncrementInt32,
IncrementUint32,
@@ -256,7 +256,7 @@
virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
virtual status_t increment(const std::vector<TestParcelable>& a,
std::vector<TestParcelable>* aPlusOne) const = 0;
- virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
+ virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
// As mentioned above, sp<IBinder> is already tested by setDeathToken
virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
@@ -329,9 +329,10 @@
std::vector<TestParcelable>*);
return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
}
- status_t toUpper(const String8& str, String8* upperStr) const override {
+ status_t doubleString(const String8& str, String8* doubleStr) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
- return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
+ return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
+ doubleStr);
}
void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
@@ -454,10 +455,9 @@
}
return NO_ERROR;
}
- status_t toUpper(const String8& str, String8* upperStr) const override {
+ status_t doubleString(const String8& str, String8* doubleStr) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
- *upperStr = str;
- upperStr->toUpper();
+ *doubleStr = str + str;
return NO_ERROR;
}
void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
@@ -548,8 +548,8 @@
std::vector<TestParcelable>*) const;
return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
}
- case ISafeInterfaceTest::Tag::ToUpper: {
- return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
+ case ISafeInterfaceTest::Tag::DoubleString: {
+ return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
}
case ISafeInterfaceTest::Tag::CallMeBack: {
return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
@@ -726,12 +726,12 @@
}
}
-TEST_F(SafeInterfaceTest, TestToUpper) {
- const String8 str{"Hello, world!"};
- String8 upperStr;
- status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
+TEST_F(SafeInterfaceTest, TestDoubleString) {
+ const String8 str{"asdf"};
+ String8 doubleStr;
+ status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
ASSERT_EQ(NO_ERROR, result);
- ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
+ ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
}
TEST_F(SafeInterfaceTest, TestCallMeBack) {
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 4270540..cb309bd 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android/binder_libbinder.h>
#include <android/binder_manager.h>
#include <android/binder_stability.h>
#include <binder/Binder.h>
@@ -131,17 +132,55 @@
EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf()));
}
-TEST(BinderStability, ForceDowngradeStability) {
+TEST(BinderStability, ForceDowngradeToLocalStability) {
sp<IBinder> someBinder = BadStableBinder::vintf();
EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder));
// silly to do this after already using the binder, but it's for the test
- Stability::forceDowngradeCompilationUnit(someBinder);
+ Stability::forceDowngradeToLocalStability(someBinder);
EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder));
}
+TEST(BinderStability, NdkForceDowngradeToLocalStability) {
+ sp<IBinder> someBinder = BadStableBinder::vintf();
+
+ EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder));
+
+ // silly to do this after already using the binder, but it's for the test
+ AIBinder_forceDowngradeToLocalStability(AIBinder_fromPlatformBinder(someBinder));
+
+ EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder));
+}
+
+TEST(BinderStability, ForceDowngradeToVendorStability) {
+ sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
+ auto server = interface_cast<IBinderStabilityTest>(serverBinder);
+
+ ASSERT_NE(nullptr, server.get());
+ ASSERT_NE(nullptr, IInterface::asBinder(server)->remoteBinder());
+
+ {
+ sp<BadStableBinder> binder = BadStableBinder::vintf();
+
+ EXPECT_TRUE(Stability::requiresVintfDeclaration(binder));
+ EXPECT_TRUE(server->sendAndCallBinder(binder).isOk());
+ EXPECT_TRUE(binder->gotUserTransaction);
+ }
+ {
+ sp<BadStableBinder> binder = BadStableBinder::vintf();
+
+ // This method should never be called directly. This is done only for the test.
+ Stability::forceDowngradeToVendorStability(binder);
+
+ // Binder downgraded to vendor stability, cannot be called from system context
+ EXPECT_FALSE(Stability::requiresVintfDeclaration(binder));
+ EXPECT_EQ(BAD_TYPE, server->sendAndCallBinder(binder).exceptionCode());
+ EXPECT_FALSE(binder->gotUserTransaction);
+ }
+}
+
TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) {
sp<IBinder> vintfServer = BadStableBinder::vintf();
diff --git a/libs/binder/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
similarity index 100%
rename from libs/binder/parcel_fuzzer/Android.bp
rename to libs/binder/tests/parcel_fuzzer/Android.bp
diff --git a/libs/binder/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
similarity index 100%
rename from libs/binder/parcel_fuzzer/binder.cpp
rename to libs/binder/tests/parcel_fuzzer/binder.cpp
diff --git a/libs/binder/parcel_fuzzer/binder.h b/libs/binder/tests/parcel_fuzzer/binder.h
similarity index 100%
rename from libs/binder/parcel_fuzzer/binder.h
rename to libs/binder/tests/parcel_fuzzer/binder.h
diff --git a/libs/binder/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
similarity index 100%
rename from libs/binder/parcel_fuzzer/binder_ndk.cpp
rename to libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
diff --git a/libs/binder/parcel_fuzzer/binder_ndk.h b/libs/binder/tests/parcel_fuzzer/binder_ndk.h
similarity index 97%
rename from libs/binder/parcel_fuzzer/binder_ndk.h
rename to libs/binder/tests/parcel_fuzzer/binder_ndk.h
index e69d9c1..cf24ab9 100644
--- a/libs/binder/parcel_fuzzer/binder_ndk.h
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.h
@@ -23,7 +23,7 @@
// libbinder_ndk doesn't export this header which breaks down its API for NDK
// and APEX users, but we need access to it to fuzz.
-#include "../ndk/parcel_internal.h"
+#include "../../ndk/parcel_internal.h"
class NdkParcelAdapter {
public:
diff --git a/libs/binder/parcel_fuzzer/hwbinder.cpp b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
similarity index 100%
rename from libs/binder/parcel_fuzzer/hwbinder.cpp
rename to libs/binder/tests/parcel_fuzzer/hwbinder.cpp
diff --git a/libs/binder/parcel_fuzzer/hwbinder.h b/libs/binder/tests/parcel_fuzzer/hwbinder.h
similarity index 100%
rename from libs/binder/parcel_fuzzer/hwbinder.h
rename to libs/binder/tests/parcel_fuzzer/hwbinder.h
diff --git a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
similarity index 100%
rename from libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
rename to libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
diff --git a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
similarity index 80%
rename from libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
rename to libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
index b92a6a9..749bf21 100644
--- a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
@@ -20,5 +20,12 @@
#include <fuzzer/FuzzedDataProvider.h>
namespace android {
+/**
+ * Fill parcel data, including some random binder objects and FDs
+ */
void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider);
+/**
+ * Fill parcel data, but don't fill any objects.
+ */
+void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider);
} // namespace android
diff --git a/libs/binder/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp
similarity index 89%
rename from libs/binder/parcel_fuzzer/main.cpp
rename to libs/binder/tests/parcel_fuzzer/main.cpp
index 78606cc..332e2ad 100644
--- a/libs/binder/parcel_fuzzer/main.cpp
+++ b/libs/binder/tests/parcel_fuzzer/main.cpp
@@ -23,6 +23,7 @@
#include <iostream>
#include <android-base/logging.h>
+#include <binder/RpcConnection.h>
#include <fuzzbinder/random_parcel.h>
#include <fuzzer/FuzzedDataProvider.h>
@@ -32,6 +33,8 @@
#include <sys/time.h>
using android::fillRandomParcel;
+using android::RpcConnection;
+using android::sp;
void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) {
// TODO: functionality to create random parcels for libhwbinder parcels
@@ -56,7 +59,18 @@
provider.ConsumeIntegralInRange<size_t>(0, maxInstructions));
P p;
- fillRandomParcel(&p, std::move(provider));
+ if constexpr (std::is_same_v<P, android::Parcel>) {
+ if (provider.ConsumeBool()) {
+ auto connection = sp<RpcConnection>::make();
+ CHECK(connection->addNullDebuggingClient());
+ p.markForRpc(connection);
+ fillRandomParcelData(&p, std::move(provider));
+ } else {
+ fillRandomParcel(&p, std::move(provider));
+ }
+ } else {
+ fillRandomParcel(&p, std::move(provider));
+ }
// since we are only using a byte to index
CHECK(reads.size() <= 255) << reads.size();
diff --git a/libs/binder/parcel_fuzzer/parcel_fuzzer.h b/libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h
similarity index 100%
rename from libs/binder/parcel_fuzzer/parcel_fuzzer.h
rename to libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h
diff --git a/libs/binder/parcel_fuzzer/random_fd.cpp b/libs/binder/tests/parcel_fuzzer/random_fd.cpp
similarity index 100%
rename from libs/binder/parcel_fuzzer/random_fd.cpp
rename to libs/binder/tests/parcel_fuzzer/random_fd.cpp
diff --git a/libs/binder/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
similarity index 93%
rename from libs/binder/parcel_fuzzer/random_parcel.cpp
rename to libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 9ca4c8a..b045a22 100644
--- a/libs/binder/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -75,4 +75,9 @@
}
}
+void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) {
+ std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(provider.remaining_bytes());
+ CHECK(OK == p->write(data.data(), data.size()));
+}
+
} // namespace android
diff --git a/libs/binder/parcel_fuzzer/util.cpp b/libs/binder/tests/parcel_fuzzer/util.cpp
similarity index 100%
rename from libs/binder/parcel_fuzzer/util.cpp
rename to libs/binder/tests/parcel_fuzzer/util.cpp
diff --git a/libs/binder/parcel_fuzzer/util.h b/libs/binder/tests/parcel_fuzzer/util.h
similarity index 100%
rename from libs/binder/parcel_fuzzer/util.h
rename to libs/binder/tests/parcel_fuzzer/util.h
diff --git a/libs/binder/tests/fuzzers/Android.bp b/libs/binder/tests/unit_fuzzers/Android.bp
similarity index 100%
rename from libs/binder/tests/fuzzers/Android.bp
rename to libs/binder/tests/unit_fuzzers/Android.bp
diff --git a/libs/binder/tests/fuzzers/BinderFuzz.cpp b/libs/binder/tests/unit_fuzzers/BinderFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/BinderFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/BinderFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/BinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/BinderFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/BpBinderFuzz.cpp b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/BpBinderFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/BufferedTextOutputFuzz.cpp b/libs/binder/tests/unit_fuzzers/BufferedTextOutputFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/BufferedTextOutputFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/BufferedTextOutputFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/IBinderFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/MemoryDealerFuzz.cpp b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/MemoryDealerFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp b/libs/binder/tests/unit_fuzzers/PersistableBundleFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/PersistableBundleFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/PersistableBundleFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/PersistableBundleFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/StabilityFuzz.cpp b/libs/binder/tests/unit_fuzzers/StabilityFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/StabilityFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/StabilityFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/StabilityFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/StabilityFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/StatusFuzz.cpp b/libs/binder/tests/unit_fuzzers/StatusFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/StatusFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/StatusFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/StatusFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/StatusFuzzFunctions.h
similarity index 100%
rename from libs/binder/tests/fuzzers/StatusFuzzFunctions.h
rename to libs/binder/tests/unit_fuzzers/StatusFuzzFunctions.h
diff --git a/libs/binder/tests/fuzzers/TextOutputFuzz.cpp b/libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp
similarity index 100%
rename from libs/binder/tests/fuzzers/TextOutputFuzz.cpp
rename to libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp
diff --git a/libs/binder/tests/fuzzers/commonFuzzHelpers.h b/libs/binder/tests/unit_fuzzers/commonFuzzHelpers.h
similarity index 100%
rename from libs/binder/tests/fuzzers/commonFuzzHelpers.h
rename to libs/binder/tests/unit_fuzzers/commonFuzzHelpers.h
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
new file mode 100644
index 0000000..dd38224
--- /dev/null
+++ b/libs/permission/Android.bp
@@ -0,0 +1,14 @@
+cc_library_shared {
+ name: "libpermission",
+ srcs: [
+ "AppOpsManager.cpp",
+ "IAppOpsCallback.cpp",
+ "IAppOpsService.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+}
diff --git a/libs/binder/AppOpsManager.cpp b/libs/permission/AppOpsManager.cpp
similarity index 98%
rename from libs/binder/AppOpsManager.cpp
rename to libs/permission/AppOpsManager.cpp
index 1c6b491..f3ea1a7 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/permission/AppOpsManager.cpp
@@ -36,7 +36,7 @@
pthread_mutex_lock(&gClientIdMutex);
if (gClientId == nullptr) {
- gClientId = new BBinder();
+ gClientId = sp<BBinder>::make();
}
pthread_mutex_unlock(&gClientIdMutex);
return gClientId;
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/permission/IAppOpsCallback.cpp
similarity index 100%
rename from libs/binder/IAppOpsCallback.cpp
rename to libs/permission/IAppOpsCallback.cpp
diff --git a/libs/binder/IAppOpsService.cpp b/libs/permission/IAppOpsService.cpp
similarity index 100%
rename from libs/binder/IAppOpsService.cpp
rename to libs/permission/IAppOpsService.cpp
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h
similarity index 100%
rename from libs/binder/include/binder/AppOpsManager.h
rename to libs/permission/include/binder/AppOpsManager.h
diff --git a/libs/binder/include/binder/IAppOpsCallback.h b/libs/permission/include/binder/IAppOpsCallback.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsCallback.h
rename to libs/permission/include/binder/IAppOpsCallback.h
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/permission/include/binder/IAppOpsService.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsService.h
rename to libs/permission/include/binder/IAppOpsService.h
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 497c33c..edd453a 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -48,11 +48,10 @@
"libutils",
"liblog",
"libhardware",
+ "libpermission",
],
export_include_dirs: ["include"],
- export_shared_lib_headers: ["libbinder", "libhardware"],
+ export_shared_lib_headers: ["libbinder", "libpermission", "libhardware"],
}
-
-subdirs = ["tests"]
diff --git a/services/memtrackproxy/Android.bp b/services/memtrackproxy/Android.bp
new file mode 100644
index 0000000..7d78f3b
--- /dev/null
+++ b/services/memtrackproxy/Android.bp
@@ -0,0 +1,50 @@
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_library_shared {
+ name: "libmemtrackproxy",
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libbinder",
+ "libhidlbase",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "android.hardware.memtrack@1.0",
+ "android.hardware.memtrack-V1-ndk_platform",
+ ],
+ srcs: [
+ "MemtrackProxy.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ local_include_dirs: [
+ "include/memtrackproxy",
+ ],
+ export_shared_lib_headers: [
+ "android.hardware.memtrack@1.0",
+ "android.hardware.memtrack-V1-ndk_platform",
+ ],
+}
diff --git a/services/memtrackproxy/MemtrackProxy.cpp b/services/memtrackproxy/MemtrackProxy.cpp
new file mode 100644
index 0000000..4676167
--- /dev/null
+++ b/services/memtrackproxy/MemtrackProxy.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2021 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 "MemtrackProxy.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <private/android_filesystem_config.h>
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace memtrack {
+
+// Check Memtrack Flags
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_ACCOUNTED) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_ACCOUNTED));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_UNACCOUNTED) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_UNACCOUNTED));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED_PSS) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED_PSS));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::PRIVATE) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_PRIVATE));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SYSTEM) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SYSTEM));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::DEDICATED) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_DEDICATED));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::NONSECURE) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_NONSECURE));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SECURE) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SECURE));
+
+// Check Memtrack Types
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::OTHER) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackType::OTHER));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GL) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackType::GL));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GRAPHICS) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackType::GRAPHICS));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::MULTIMEDIA) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackType::MULTIMEDIA));
+static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::CAMERA) ==
+ static_cast<uint32_t>(V1_aidl::MemtrackType::CAMERA));
+
+__attribute__((warn_unused_result)) bool translate(const V1_0_hidl::MemtrackRecord& in,
+ V1_aidl::MemtrackRecord* out) {
+ // Convert uint64_t to int64_t (long in AIDL). AIDL doesn't support unsigned types.
+ if (in.sizeInBytes > std::numeric_limits<int64_t>::max() || in.sizeInBytes < 0) {
+ return false;
+ }
+ out->sizeInBytes = static_cast<int64_t>(in.sizeInBytes);
+
+ // It's ok to just assign directly, since this is a bitmap.
+ out->flags = in.flags;
+ return true;
+}
+
+sp<V1_0_hidl::IMemtrack> MemtrackProxy::MemtrackHidlInstance() {
+ return V1_0_hidl::IMemtrack::getService();
+}
+
+std::shared_ptr<V1_aidl::IMemtrack> MemtrackProxy::MemtrackAidlInstance() {
+ const auto instance = std::string() + V1_aidl::IMemtrack::descriptor + "/default";
+ bool declared = AServiceManager_isDeclared(instance.c_str());
+ if (!declared) {
+ return nullptr;
+ }
+ ndk::SpAIBinder memtrack_binder =
+ ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str()));
+ return V1_aidl::IMemtrack::fromBinder(memtrack_binder);
+}
+
+bool MemtrackProxy::CheckUid(uid_t calling_uid) {
+ // Allow AID_SHELL for adb shell dumpsys meminfo
+ return calling_uid == AID_SYSTEM || calling_uid == AID_ROOT || calling_uid == AID_SHELL;
+}
+
+bool MemtrackProxy::CheckPid(pid_t calling_pid, pid_t request_pid) {
+ return calling_pid == request_pid;
+}
+
+MemtrackProxy::MemtrackProxy()
+ : memtrack_hidl_instance_(MemtrackProxy::MemtrackHidlInstance()),
+ memtrack_aidl_instance_(MemtrackProxy::MemtrackAidlInstance()) {}
+
+ndk::ScopedAStatus MemtrackProxy::getMemory(int pid, MemtrackType type,
+ std::vector<MemtrackRecord>* _aidl_return) {
+ if (pid < 0) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ if (!MemtrackProxy::CheckPid(AIBinder_getCallingPid(), pid) &&
+ !MemtrackProxy::CheckUid(AIBinder_getCallingUid())) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_SECURITY,
+ "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getMemory() for PIDs other "
+ "than the calling PID");
+ }
+
+ if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
+ type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+
+ _aidl_return->clear();
+
+ if (memtrack_aidl_instance_) {
+ return memtrack_aidl_instance_->getMemory(pid, type, _aidl_return);
+ } else if (memtrack_hidl_instance_) {
+ ndk::ScopedAStatus aidl_status;
+
+ Return<void> ret = memtrack_hidl_instance_->getMemory(
+ pid, static_cast<V1_0_hidl::MemtrackType>(type),
+ [&_aidl_return, &aidl_status](V1_0_hidl::MemtrackStatus status,
+ hidl_vec<V1_0_hidl::MemtrackRecord> records) {
+ switch (status) {
+ case V1_0_hidl::MemtrackStatus::SUCCESS:
+ aidl_status = ndk::ScopedAStatus::ok();
+ break;
+ case V1_0_hidl::MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED:
+ [[fallthrough]];
+ case V1_0_hidl::MemtrackStatus::TYPE_NOT_SUPPORTED:
+ [[fallthrough]];
+ default:
+ aidl_status =
+ ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ return;
+ }
+
+ _aidl_return->resize(records.size());
+ for (size_t i = 0; i < records.size(); i++) {
+ if (!translate(records[i], &(*_aidl_return)[i])) {
+ aidl_status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_SERVICE_SPECIFIC,
+ "Failed to convert HIDL MemtrackRecord to AIDL");
+ return;
+ }
+ }
+ });
+
+ // Check HIDL return
+ if (!ret.isOk()) {
+ const char* err_msg = "HIDL Memtrack::getMemory() failed";
+ aidl_status =
+ ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC, err_msg);
+ LOG(ERROR) << err_msg << ": " << ret.description();
+ }
+
+ return aidl_status;
+ }
+
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
+ "Memtrack HAL service not available");
+}
+
+ndk::ScopedAStatus MemtrackProxy::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) {
+ if (!MemtrackProxy::CheckUid(AIBinder_getCallingUid())) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SECURITY,
+ "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getGpuDeviceInfo()");
+ }
+
+ _aidl_return->clear();
+
+ if (memtrack_aidl_instance_ ||
+ (memtrack_aidl_instance_ = MemtrackProxy::MemtrackAidlInstance())) {
+ return memtrack_aidl_instance_->getGpuDeviceInfo(_aidl_return);
+ }
+
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
+ "Memtrack HAL service not available");
+}
+
+} // namespace memtrack
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h b/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h
new file mode 100644
index 0000000..5ac1fbf
--- /dev/null
+++ b/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/memtrack/BnMemtrack.h>
+#include <aidl/android/hardware/memtrack/DeviceInfo.h>
+#include <aidl/android/hardware/memtrack/IMemtrack.h>
+#include <aidl/android/hardware/memtrack/MemtrackRecord.h>
+#include <aidl/android/hardware/memtrack/MemtrackType.h>
+#include <android/hardware/memtrack/1.0/IMemtrack.h>
+
+using ::android::sp;
+
+namespace V1_0_hidl = ::android::hardware::memtrack::V1_0;
+namespace V1_aidl = ::aidl::android::hardware::memtrack;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace memtrack {
+
+__attribute__((warn_unused_result)) bool translate(const V1_0_hidl::MemtrackRecord& in,
+ V1_aidl::MemtrackRecord* out);
+
+class MemtrackProxy : public BnMemtrack {
+public:
+ MemtrackProxy();
+ ndk::ScopedAStatus getMemory(int pid, MemtrackType type,
+ std::vector<MemtrackRecord>* _aidl_return) override;
+ ndk::ScopedAStatus getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) override;
+
+private:
+ static sp<V1_0_hidl::IMemtrack> MemtrackHidlInstance();
+ static std::shared_ptr<V1_aidl::IMemtrack> MemtrackAidlInstance();
+ static bool CheckUid(uid_t calling_uid);
+ static bool CheckPid(pid_t calling_pid, pid_t request_pid);
+
+ sp<V1_0_hidl::IMemtrack> memtrack_hidl_instance_;
+ std::shared_ptr<V1_aidl::IMemtrack> memtrack_aidl_instance_;
+};
+
+} // namespace memtrack
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/services/memtrackproxy/test/Android.bp b/services/memtrackproxy/test/Android.bp
new file mode 100644
index 0000000..f943761
--- /dev/null
+++ b/services/memtrackproxy/test/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2021 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_test {
+ name: "memtrackproxy_test",
+ srcs: [
+ "MemtrackProxyTest.cpp",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libmemtrackproxy",
+ "android.hardware.memtrack-V1-ndk_platform",
+ ],
+ test_suites: ["general-tests"],
+ require_root: true,
+}
diff --git a/services/memtrackproxy/test/MemtrackProxyTest.cpp b/services/memtrackproxy/test/MemtrackProxyTest.cpp
new file mode 100644
index 0000000..16dfba0
--- /dev/null
+++ b/services/memtrackproxy/test/MemtrackProxyTest.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/memtrack/DeviceInfo.h>
+#include <aidl/android/hardware/memtrack/IMemtrack.h>
+#include <aidl/android/hardware/memtrack/MemtrackRecord.h>
+#include <aidl/android/hardware/memtrack/MemtrackType.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+using aidl::android::hardware::memtrack::DeviceInfo;
+using aidl::android::hardware::memtrack::IMemtrack;
+using aidl::android::hardware::memtrack::MemtrackRecord;
+using aidl::android::hardware::memtrack::MemtrackType;
+
+class MemtrackProxyTest : public ::testing::Test {
+public:
+ virtual void SetUp() override {
+ const char* kMemtrackProxyService = "memtrack.proxy";
+ auto memtrackProxyBinder =
+ ndk::SpAIBinder(AServiceManager_waitForService(kMemtrackProxyService));
+ memtrack_proxy_ = IMemtrack::fromBinder(memtrackProxyBinder);
+ ASSERT_NE(memtrack_proxy_, nullptr);
+ }
+
+ std::shared_ptr<IMemtrack> memtrack_proxy_;
+};
+
+TEST_F(MemtrackProxyTest, GetMemoryForInvalidPid) {
+ int pid = -1;
+
+ for (MemtrackType type : ndk::enum_range<MemtrackType>()) {
+ std::vector<MemtrackRecord> records;
+
+ auto status = memtrack_proxy_->getMemory(pid, type, &records);
+
+ EXPECT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ }
+}
+
+TEST_F(MemtrackProxyTest, GetMemoryForCallingPid) {
+ int pid = getpid();
+
+ for (MemtrackType type : ndk::enum_range<MemtrackType>()) {
+ std::vector<MemtrackRecord> records;
+
+ auto status = memtrack_proxy_->getMemory(pid, type, &records);
+
+ EXPECT_TRUE(status.isOk());
+ }
+}
+
+TEST_F(MemtrackProxyTest, GetMemoryForOtherPid) {
+ int pid = 1;
+
+ for (MemtrackType type : ndk::enum_range<MemtrackType>()) {
+ std::vector<MemtrackRecord> records;
+
+ auto status = memtrack_proxy_->getMemory(pid, type, &records);
+
+ // Test is run as root
+ EXPECT_TRUE(status.isOk());
+ }
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index ca9ff7c..4151b45 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -7,9 +7,6 @@
default_applicable_licenses: ["frameworks_native_license"],
}
-subdirs = [
- "hidl"
-]
cc_library_shared {
name: "libsensorservice",
@@ -52,9 +49,12 @@
"libhardware_legacy",
"libutils",
"liblog",
+ "libactivitymanager_aidl",
+ "libbatterystats_aidl",
"libbinder",
"libsensor",
"libsensorprivacy",
+ "libpermission",
"libprotoutil",
"libcrypto",
"libbase",
@@ -71,8 +71,12 @@
generated_headers: ["framework-cppstream-protos"],
- // our public headers depend on libsensor and libsensorprivacy
- export_shared_lib_headers: ["libsensor", "libsensorprivacy"],
+ export_shared_lib_headers: [
+ "libactivitymanager_aidl",
+ "libsensor",
+ "libsensorprivacy",
+ "libpermission",
+ ],
}
cc_binary {
diff --git a/services/sensorservice/BatteryService.h b/services/sensorservice/BatteryService.h
index 43a750c..09eb2c1 100644
--- a/services/sensorservice/BatteryService.h
+++ b/services/sensorservice/BatteryService.h
@@ -17,7 +17,7 @@
#include <stdint.h>
#include <sys/types.h>
-#include <binder/IBatteryStats.h>
+#include <batterystats/IBatteryStats.h>
#include <utils/Singleton.h>
namespace android {
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index df26a3d..5a24d51 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -211,8 +211,8 @@
layer.frameNumber = mCurrentFrameNumber;
layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0;
- // TODO: we could be more subtle with isFixedSize()
- const bool useFiltering = targetSettings.needsFiltering || mNeedsFiltering || isFixedSize();
+ const bool useFiltering =
+ targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering();
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
@@ -847,6 +847,36 @@
}
}
+bool BufferLayer::bufferNeedsFiltering() const {
+ // Layers that don't resize along with their buffer, don't need filtering.
+ if (!isFixedSize()) {
+ return false;
+ }
+
+ if (!mBufferInfo.mBuffer) {
+ return false;
+ }
+
+ uint32_t bufferWidth = mBufferInfo.mBuffer->width;
+ uint32_t bufferHeight = mBufferInfo.mBuffer->height;
+
+ // Undo any transformations on the buffer and return the result.
+ const State& s(getDrawingState());
+ if (s.transform & ui::Transform::ROT_90) {
+ std::swap(bufferWidth, bufferHeight);
+ }
+
+ if (s.transformToDisplayInverse) {
+ uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
+ if (invTransform & ui::Transform::ROT_90) {
+ std::swap(bufferWidth, bufferHeight);
+ }
+ }
+
+ const Rect layerSize{getBounds()};
+ return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight;
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 26bfb49..c7e8ad7 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -118,6 +118,10 @@
ui::Transform::RotationFlags getTransformHint() const override { return mTransformHint; }
+ // Returns true if the transformed buffer size does not match the layer size and we need
+ // to apply filtering.
+ bool bufferNeedsFiltering() const;
+
// -----------------------------------------------------------------------
// Functions that must be implemented by derived classes
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 790f2ec..41dd7bf 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -760,6 +760,7 @@
static_cast<float>(s.active.transform.ty() + s.active.h)),
radius);
}
+
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 866007e..eb24a22 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -108,6 +108,7 @@
cc_binary {
name: "vr_hwc",
+ enabled: false,
system_ext_specific: true,
vintf_fragments: ["manifest_vr_hwc.xml"],
srcs: [
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 4b69bec..2913850 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1088,7 +1088,8 @@
ALOGW_IF(err != android::OK, "native_window_api_connect failed: %s (%d)",
strerror(-err), err);
- err = window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, -1);
+ err =
+ window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, nsecs_t{-1});
if (err != android::OK) {
ALOGE("window->perform(SET_DEQUEUE_TIMEOUT) failed: %s (%d)",
strerror(-err), err);
diff --git a/vulkan/vkjson/vkjson_instance.cc b/vulkan/vkjson/vkjson_instance.cc
index 73586d4..c3f4963 100644
--- a/vulkan/vkjson/vkjson_instance.cc
+++ b/vulkan/vkjson/vkjson_instance.cc
@@ -433,6 +433,10 @@
VkJsonDeviceGroup device_group;
std::vector<VkPhysicalDeviceGroupProperties> group_properties;
group_properties.resize(count);
+ for (auto& properties : group_properties) {
+ properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
+ properties.pNext = nullptr;
+ }
result = (*vkpEnumeratePhysicalDeviceGroups)(vkinstance, &count,
group_properties.data());
if (result != VK_SUCCESS) {