Merge "Add mechanism for a task's windows to be trusted overlays (SF)" into sc-dev am: 5eaa7c3136 am: a0de3613cf
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15150900
Change-Id: I27c503bb7d948499ebadafbd65dfdaf570d95d81
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 79419d3..9a8ec32 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -126,7 +126,6 @@
{ "aidl", "AIDL calls", ATRACE_TAG_AIDL, { } },
{ "nnapi", "NNAPI", ATRACE_TAG_NNAPI, { } },
{ "rro", "Runtime Resource Overlay", ATRACE_TAG_RRO, { } },
- { "sysprop", "System Property", ATRACE_TAG_SYSPROP, { } },
{ k_coreServiceCategory, "Core services", 0, { } },
{ k_pdxServiceCategory, "PDX services", 0, { } },
{ "sched", "CPU Scheduling", 0, {
@@ -245,6 +244,7 @@
{ OPT, "events/kmem/ion_heap_shrink/enable" },
{ OPT, "events/ion/ion_stat/enable" },
{ OPT, "events/gpu_mem/gpu_mem_total/enable" },
+ { OPT, "events/fastrpc/fastrpc_dma_stat/enable" },
} },
{ "thermal", "Thermal event", 0, {
{ REQ, "events/thermal/thermal_temperature/enable" },
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 2d11b90..75505f3 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1237,7 +1237,7 @@
std::string path(title);
path.append(" - ").append(String8(service).c_str());
size_t bytes_written = 0;
- status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args);
+ status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP, service, args);
if (status == OK) {
dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
std::chrono::duration<double> elapsed_seconds;
@@ -1316,7 +1316,7 @@
path.append("_HIGH");
}
path.append(kProtoExt);
- status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args);
+ status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP, service, args);
if (status == OK) {
status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout);
bool dumpTerminated = (status == OK);
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index ba1c449..f8fdaa0 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -24,6 +24,7 @@
#include <android-base/unique_fd.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
+#include <binder/Stability.h>
#include <binder/TextOutput.h>
#include <binderdebug/BinderDebug.h>
#include <serviceutils/PriorityDumper.h>
@@ -61,20 +62,22 @@
"usage: dumpsys\n"
" To dump all services.\n"
"or:\n"
- " dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--thread] [--help | -l | "
- "--skip SERVICES "
+ " dumpsys [-t TIMEOUT] [--priority LEVEL] [--dump] [--pid] [--thread] [--help | "
+ "-l | --skip SERVICES "
"| SERVICE [ARGS]]\n"
" --help: shows this help\n"
" -l: only list services, do not dump them\n"
" -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n"
" -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n"
+ " --dump: ask the service to dump itself (this is the default)\n"
" --pid: dump PID instead of usual dump\n"
- " --thread: dump thread usage instead of usual dump\n"
" --proto: filter services that support dumping data in proto format. Dumps\n"
" will be in proto format.\n"
" --priority LEVEL: filter services based on specified priority\n"
" LEVEL must be one of CRITICAL | HIGH | NORMAL\n"
" --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
+ " --stability: dump binder stability information instead of usual dump\n"
+ " --thread: dump thread usage instead of usual dump\n"
" SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
}
@@ -125,15 +128,17 @@
bool showListOnly = false;
bool skipServices = false;
bool asProto = false;
- Type type = Type::DUMP;
+ int dumpTypeFlags = 0;
int timeoutArgMs = 10000;
int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
- static struct option longOptions[] = {{"thread", no_argument, 0, 0},
+ static struct option longOptions[] = {{"help", no_argument, 0, 0},
+ {"dump", no_argument, 0, 0},
{"pid", no_argument, 0, 0},
{"priority", required_argument, 0, 0},
{"proto", no_argument, 0, 0},
{"skip", no_argument, 0, 0},
- {"help", no_argument, 0, 0},
+ {"stability", no_argument, 0, 0},
+ {"thread", no_argument, 0, 0},
{0, 0, 0, 0}};
// Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
@@ -165,10 +170,14 @@
usage();
return -1;
}
+ } else if (!strcmp(longOptions[optionIndex].name, "dump")) {
+ dumpTypeFlags |= TYPE_DUMP;
} else if (!strcmp(longOptions[optionIndex].name, "pid")) {
- type = Type::PID;
+ dumpTypeFlags |= TYPE_PID;
+ } else if (!strcmp(longOptions[optionIndex].name, "stability")) {
+ dumpTypeFlags |= TYPE_STABILITY;
} else if (!strcmp(longOptions[optionIndex].name, "thread")) {
- type = Type::THREAD;
+ dumpTypeFlags |= TYPE_THREAD;
}
break;
@@ -206,6 +215,10 @@
}
}
+ if (dumpTypeFlags == 0) {
+ dumpTypeFlags = TYPE_DUMP;
+ }
+
for (int i = optind; i < argc; i++) {
if (skipServices) {
skippedServices.add(String16(argv[i]));
@@ -258,7 +271,7 @@
const String16& serviceName = services[i];
if (IsSkipped(skippedServices, serviceName)) continue;
- if (startDumpThread(type, serviceName, args) == OK) {
+ if (startDumpThread(dumpTypeFlags, serviceName, args) == OK) {
bool addSeparator = (N > 1);
if (addSeparator) {
writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags);
@@ -325,16 +338,24 @@
}
}
-static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd) {
+static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd, bool exclusive) {
pid_t pid;
status_t status = service->getDebugPid(&pid);
if (status != OK) {
return status;
}
+ if (!exclusive) {
+ WriteStringToFd("Service host process PID: ", fd.get());
+ }
WriteStringToFd(std::to_string(pid) + "\n", fd.get());
return OK;
}
+static status_t dumpStabilityToFd(const sp<IBinder>& service, const unique_fd& fd) {
+ WriteStringToFd("Stability: " + internal::Stability::debugToString(service) + "\n", fd);
+ return OK;
+}
+
static status_t dumpThreadsToFd(const sp<IBinder>& service, const unique_fd& fd) {
pid_t pid;
status_t status = service->getDebugPid(&pid);
@@ -352,7 +373,14 @@
return OK;
}
-status_t Dumpsys::startDumpThread(Type type, const String16& serviceName,
+static void reportDumpError(const String16& serviceName, status_t error, const char* context) {
+ if (error == OK) return;
+
+ std::cerr << "Error with service '" << serviceName << "' while " << context << ": "
+ << statusToString(error) << std::endl;
+}
+
+status_t Dumpsys::startDumpThread(int dumpTypeFlags, const String16& serviceName,
const Vector<String16>& args) {
sp<IBinder> service = sm_->checkService(serviceName);
if (service == nullptr) {
@@ -373,26 +401,23 @@
// dump blocks until completion, so spawn a thread..
activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {
- status_t err = 0;
-
- switch (type) {
- case Type::DUMP:
- err = service->dump(remote_end.get(), args);
- break;
- case Type::PID:
- err = dumpPidToFd(service, remote_end);
- break;
- case Type::THREAD:
- err = dumpThreadsToFd(service, remote_end);
- break;
- default:
- std::cerr << "Unknown dump type" << static_cast<int>(type) << std::endl;
- return;
+ if (dumpTypeFlags & TYPE_PID) {
+ status_t err = dumpPidToFd(service, remote_end, dumpTypeFlags == TYPE_PID);
+ reportDumpError(serviceName, err, "dumping PID");
+ }
+ if (dumpTypeFlags & TYPE_STABILITY) {
+ status_t err = dumpStabilityToFd(service, remote_end);
+ reportDumpError(serviceName, err, "dumping stability");
+ }
+ if (dumpTypeFlags & TYPE_THREAD) {
+ status_t err = dumpThreadsToFd(service, remote_end);
+ reportDumpError(serviceName, err, "dumping thread info");
}
- if (err != OK) {
- std::cerr << "Error dumping service info status_t: " << statusToString(err) << " "
- << serviceName << std::endl;
+ // other types always act as a header, this is usually longer
+ if (dumpTypeFlags & TYPE_DUMP) {
+ status_t err = service->dump(remote_end.get(), args);
+ reportDumpError(serviceName, err, "dumping");
}
});
return OK;
diff --git a/cmds/dumpsys/dumpsys.h b/cmds/dumpsys/dumpsys.h
index 349947c..05c5d5e 100644
--- a/cmds/dumpsys/dumpsys.h
+++ b/cmds/dumpsys/dumpsys.h
@@ -51,23 +51,25 @@
*/
static void setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags);
- enum class Type {
- DUMP, // dump using `dump` function
- PID, // dump pid of server only
- THREAD, // dump thread usage of server only
+ enum Type {
+ TYPE_DUMP = 0x1, // dump using `dump` function
+ TYPE_PID = 0x2, // dump pid of server only
+ TYPE_STABILITY = 0x4, // dump stability information of server
+ TYPE_THREAD = 0x8, // dump thread usage of server only
};
/**
* Starts a thread to connect to a service and get its dump output. The thread redirects
* the output to a pipe. Thread must be stopped by a subsequent call to {@code
* stopDumpThread}.
+ * @param dumpTypeFlags operations to perform
* @param serviceName
* @param args list of arguments to pass to service dump method.
* @return {@code OK} thread is started successfully.
* {@code NAME_NOT_FOUND} service could not be found.
* {@code != OK} error
*/
- status_t startDumpThread(Type type, const String16& serviceName,
+ status_t startDumpThread(int dumpTypeFlags, const String16& serviceName,
const Vector<String16>& args);
/**
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index c9d2dbb..312f4d7 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -200,7 +200,7 @@
CaptureStdout();
CaptureStderr();
dump_.setServiceArgs(args, supportsProto, priorityFlags);
- status_t status = dump_.startDumpThread(Dumpsys::Type::DUMP, serviceName, args);
+ status_t status = dump_.startDumpThread(Dumpsys::TYPE_DUMP, serviceName, args);
EXPECT_THAT(status, Eq(0));
status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false,
elapsedDuration, bytesWritten);
@@ -582,6 +582,27 @@
AssertOutput(std::to_string(getpid()) + "\n");
}
+// Tests 'dumpsys --stability'
+TEST_F(DumpsysTest, ListAllServicesWithStability) {
+ ExpectListServices({"Locksmith", "Valet"});
+ ExpectCheckService("Locksmith");
+ ExpectCheckService("Valet");
+
+ CallMain({"--stability"});
+
+ AssertRunningServices({"Locksmith", "Valet"});
+ AssertOutputContains("stability");
+}
+
+// Tests 'dumpsys --stability service_name'
+TEST_F(DumpsysTest, ListServiceWithStability) {
+ ExpectCheckService("Locksmith");
+
+ CallMain({"--stability", "Locksmith"});
+
+ AssertOutputContains("stability");
+}
+
// Tests 'dumpsys --thread'
TEST_F(DumpsysTest, ListAllServicesWithThread) {
ExpectListServices({"Locksmith", "Valet"});
@@ -606,6 +627,28 @@
AssertOutputFormat(format);
}
+// Tests 'dumpsys --thread --stability'
+TEST_F(DumpsysTest, ListAllServicesWithMultipleOptions) {
+ ExpectListServices({"Locksmith", "Valet"});
+ ExpectCheckService("Locksmith");
+ ExpectCheckService("Valet");
+
+ CallMain({"--pid", "--stability"});
+ AssertRunningServices({"Locksmith", "Valet"});
+
+ AssertOutputContains(std::to_string(getpid()));
+ AssertOutputContains("stability");
+}
+
+// Tests 'dumpsys --pid --stability service_name'
+TEST_F(DumpsysTest, ListServiceWithMultipleOptions) {
+ ExpectCheckService("Locksmith");
+ CallMain({"--pid", "--stability", "Locksmith"});
+
+ AssertOutputContains(std::to_string(getpid()));
+ AssertOutputContains("stability");
+}
+
TEST_F(DumpsysTest, GetBytesWritten) {
const char* serviceName = "service2";
const char* dumpContents = "dump1";
diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS
index d6807ff..643b2c2 100644
--- a/cmds/installd/OWNERS
+++ b/cmds/installd/OWNERS
@@ -4,7 +4,6 @@
jsharkey@android.com
maco@google.com
mast@google.com
-mathieuc@google.com
narayan@google.com
ngeoffray@google.com
rpl@google.com
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index bc99f4d..a5f98c2 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -142,12 +142,10 @@
}
}
- PipeRelay relay(out, err, interfaceName, instanceName);
-
- if (relay.initCheck() != OK) {
- std::string msg = "PipeRelay::initCheck() FAILED w/ " + std::to_string(relay.initCheck());
- err << msg << std::endl;
- LOG(ERROR) << msg;
+ auto relay = PipeRelay::create(out, err, interfaceName + "/" + instanceName);
+ if (!relay.ok()) {
+ err << "Unable to create PipeRelay: " << relay.error() << std::endl;
+ LOG(ERROR) << "Unable to create PipeRelay: " << relay.error();
return IO_ERROR;
}
@@ -155,7 +153,7 @@
native_handle_create(1 /* numFds */, 0 /* numInts */),
native_handle_delete);
- fdHandle->data[0] = relay.fd();
+ fdHandle->data[0] = relay.value()->fd().get();
hardware::Return<void> ret = base->debug(fdHandle.get(), convert(options));
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index 4e97636..0c3fb96 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -16,143 +16,93 @@
#include "PipeRelay.h"
-#include <sys/select.h>
-#include <sys/time.h>
+#include <sys/poll.h>
#include <sys/types.h>
#include <unistd.h>
-#include <atomic>
+#include <chrono>
+#include <optional>
-#include <utils/Thread.h>
+#include <android-base/unique_fd.h>
+
+using android::base::borrowed_fd;
+using android::base::Result;
+using android::base::unique_fd;
+using std::chrono_literals::operator""ms;
namespace android {
namespace lshal {
-
-static constexpr struct timeval READ_TIMEOUT { .tv_sec = 1, .tv_usec = 0 };
-
-static std::string getThreadName(std::string interfaceName, const std::string &instanceName) {
- auto dot = interfaceName.rfind(".");
- if (dot != std::string::npos) interfaceName = interfaceName.substr(dot + 1);
- return "RelayThread_" + interfaceName + "_" + instanceName;
+Result<std::unique_ptr<PipeRelay>> PipeRelay::create(std::ostream& os,
+ const NullableOStream<std::ostream>& err,
+ const std::string& fqName) {
+ auto pipeRelay = std::unique_ptr<PipeRelay>(new PipeRelay());
+ unique_fd rfd;
+ if (!android::base::Pipe(&rfd, &pipeRelay->mWrite)) {
+ return android::base::ErrnoError() << "pipe()";
+ }
+ // Workaround for b/111997867: need a separate FD trigger because rfd can't receive POLLHUP
+ // when the write end is closed after the write end was sent through hwbinder.
+ unique_fd rfdTrigger;
+ if (!android::base::Pipe(&rfdTrigger, &pipeRelay->mWriteTrigger)) {
+ return android::base::ErrnoError() << "pipe() for trigger";
+ }
+ pipeRelay->mThread =
+ std::make_unique<std::thread>(&PipeRelay::thread, std::move(rfd), std::move(rfdTrigger),
+ &os, &err, fqName);
+ return pipeRelay;
}
-struct PipeRelay::RelayThread : public Thread {
- explicit RelayThread(int fd, std::ostream &os, const NullableOStream<std::ostream> &err,
- const std::string &fqName);
+void PipeRelay::thread(unique_fd rfd, unique_fd rfdTrigger, std::ostream* out,
+ const NullableOStream<std::ostream>* err, std::string fqName) {
+ while (true) {
+ pollfd pfd[2];
+ pfd[0] = {.fd = rfd.get(), .events = POLLIN};
+ pfd[1] = {.fd = rfdTrigger.get(), .events = 0};
- bool threadLoop() override;
- void setFinished();
-
-private:
- int mFd;
- std::ostream &mOutStream;
- NullableOStream<std::ostream> mErrStream;
-
- // If we were to use requestExit() and exitPending() instead, threadLoop()
- // may not run at all by the time ~PipeRelay is called (i.e. debug() has
- // returned from HAL). By using our own flag, we ensure that select() and
- // read() are executed until data are drained.
- std::atomic_bool mFinished;
-
- std::string mFqName;
-
- DISALLOW_COPY_AND_ASSIGN(RelayThread);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os,
- const NullableOStream<std::ostream> &err,
- const std::string &fqName)
- : mFd(fd), mOutStream(os), mErrStream(err), mFinished(false), mFqName(fqName) {}
-
-bool PipeRelay::RelayThread::threadLoop() {
- char buffer[1024];
-
- fd_set set;
- FD_ZERO(&set);
- FD_SET(mFd, &set);
-
- struct timeval timeout = READ_TIMEOUT;
-
- int res = TEMP_FAILURE_RETRY(select(mFd + 1, &set, nullptr, nullptr, &timeout));
- if (res < 0) {
- mErrStream << "debug " << mFqName << ": select() failed";
- return false;
- }
-
- if (res == 0 || !FD_ISSET(mFd, &set)) {
- if (mFinished) {
- mErrStream << "debug " << mFqName
- << ": timeout reading from pipe, output may be truncated.";
- return false;
+ int pollRes = poll(pfd, arraysize(pfd), -1 /* infinite timeout */);
+ if (pollRes < 0) {
+ int savedErrno = errno;
+ (*err) << "debug " << fqName << ": poll() failed: " << strerror(savedErrno)
+ << std::endl;
+ break;
}
- // timeout, but debug() has not returned, so wait for HAL to finish.
- return true;
- }
- // FD_ISSET(mFd, &set) == true. Data available, start reading
- ssize_t n = TEMP_FAILURE_RETRY(read(mFd, buffer, sizeof(buffer)));
-
- if (n < 0) {
- mErrStream << "debug " << mFqName << ": read() failed";
- }
-
- if (n <= 0) {
- return false;
- }
-
- mOutStream.write(buffer, n);
-
- return true;
-}
-
-void PipeRelay::RelayThread::setFinished() {
- mFinished = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-PipeRelay::PipeRelay(std::ostream &os, const NullableOStream<std::ostream> &err,
- const std::string &interfaceName, const std::string &instanceName)
- : mInitCheck(NO_INIT) {
- int res = pipe(mFds);
-
- if (res < 0) {
- mInitCheck = -errno;
- return;
- }
-
- mThread = new RelayThread(mFds[0], os, err, interfaceName + "/" + instanceName);
- mInitCheck = mThread->run(getThreadName(interfaceName, instanceName).c_str());
-}
-
-void PipeRelay::CloseFd(int *fd) {
- if (*fd >= 0) {
- close(*fd);
- *fd = -1;
+ if (pfd[0].revents & POLLIN) {
+ char buffer[1024];
+ ssize_t n = TEMP_FAILURE_RETRY(read(rfd.get(), buffer, sizeof(buffer)));
+ if (n < 0) {
+ int savedErrno = errno;
+ (*err) << "debug " << fqName << ": read() failed: " << strerror(savedErrno)
+ << std::endl;
+ break;
+ }
+ if (n == 0) {
+ (*err) << "Warning: debug " << fqName << ": poll() indicates POLLIN but no data"
+ << std::endl;
+ continue;
+ }
+ out->write(buffer, n);
+ }
+ if (pfd[0].revents & POLLHUP) {
+ break;
+ }
+ if (pfd[1].revents & POLLHUP) {
+ // ~PipeRelay is called on the main thread. |mWrite| has been flushed and closed.
+ // Ensure that our read end of the pipe doesn't have pending data, then exit.
+ if ((pfd[0].revents & POLLIN) == 0) {
+ break;
+ }
+ }
}
}
PipeRelay::~PipeRelay() {
- CloseFd(&mFds[1]);
-
- if (mThread != nullptr) {
- mThread->setFinished();
+ mWrite.reset();
+ mWriteTrigger.reset();
+ if (mThread != nullptr && mThread->joinable()) {
mThread->join();
- mThread.clear();
}
-
- CloseFd(&mFds[0]);
}
-status_t PipeRelay::initCheck() const {
- return mInitCheck;
-}
-
-int PipeRelay::fd() const {
- return mFds[1];
-}
-
-} // namespace lshal
-} // namespace android
+} // namespace lshal
+} // namespace android
diff --git a/cmds/lshal/PipeRelay.h b/cmds/lshal/PipeRelay.h
index bd994b4..45ba982 100644
--- a/cmds/lshal/PipeRelay.h
+++ b/cmds/lshal/PipeRelay.h
@@ -16,42 +16,43 @@
#pragma once
+#include <thread>
+
#include <android-base/macros.h>
-#include <ostream>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include <ostream>
#include "NullableOStream.h"
namespace android {
namespace lshal {
-/* Creates an AF_UNIX socketpair and spawns a thread that relays any data
+/**
+ * Creates a pipe and spawns a thread that relays any data
* written to the "write"-end of the pair to the specified output stream "os".
*/
struct PipeRelay {
- explicit PipeRelay(std::ostream& os,
- const NullableOStream<std::ostream>& err,
- const std::string& interfaceName,
- const std::string& instanceName);
+ static android::base::Result<std::unique_ptr<PipeRelay>> create(
+ std::ostream& os, const NullableOStream<std::ostream>& err, const std::string& fqName);
~PipeRelay();
- status_t initCheck() const;
-
// Returns the file descriptor corresponding to the "write"-end of the
// connection.
- int fd() const;
+ android::base::borrowed_fd fd() const { return mWrite; }
private:
- struct RelayThread;
-
- status_t mInitCheck;
- int mFds[2];
- sp<RelayThread> mThread;
-
- static void CloseFd(int *fd);
-
+ PipeRelay() = default;
DISALLOW_COPY_AND_ASSIGN(PipeRelay);
+ static void thread(android::base::unique_fd rfd, android::base::unique_fd rfdTrigger,
+ std::ostream* out, const NullableOStream<std::ostream>* err,
+ std::string fqName);
+
+ android::base::unique_fd mWrite;
+ android::base::unique_fd mWriteTrigger;
+ std::unique_ptr<std::thread> mThread;
};
} // namespace lshal
diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto
index 03a2709..a177027 100644
--- a/cmds/surfacereplayer/proto/src/trace.proto
+++ b/cmds/surfacereplayer/proto/src/trace.proto
@@ -101,6 +101,10 @@
required uint32 layer_stack = 1;
}
+message DisplayFlagsChange {
+ required uint32 flags = 1;
+}
+
message HiddenFlagChange {
required bool hidden_flag = 1;
}
@@ -121,6 +125,7 @@
LayerStackChange layer_stack = 3;
SizeChange size = 4;
ProjectionChange projection = 5;
+ DisplayFlagsChange flags = 6;
}
}
@@ -217,4 +222,4 @@
message Origin {
required int32 pid = 1;
required int32 uid = 2;
-}
\ No newline at end of file
+}
diff --git a/include/android/input.h b/include/android/input.h
index bb98beb..f03facb 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -169,6 +169,9 @@
/** Drag event */
AINPUT_EVENT_TYPE_DRAG = 5,
+
+ /** TouchMode event */
+ AINPUT_EVENT_TYPE_TOUCH_MODE = 6,
};
/**
diff --git a/include/input/Flags.h b/include/ftl/Flags.h
similarity index 98%
rename from include/input/Flags.h
rename to include/ftl/Flags.h
index b12a9ed..27c8476 100644
--- a/include/input/Flags.h
+++ b/include/ftl/Flags.h
@@ -22,11 +22,10 @@
#include <string>
#include <type_traits>
-#include "NamedEnum.h"
+#include <ftl/NamedEnum.h>
#include "utils/BitSet.h"
-#ifndef __UI_INPUT_FLAGS_H
-#define __UI_INPUT_FLAGS_H
+#pragma once
namespace android {
@@ -279,5 +278,3 @@
} // namespace flag_operators
} // namespace android
-
-#endif // __UI_INPUT_FLAGS_H
diff --git a/include/input/NamedEnum.h b/include/ftl/NamedEnum.h
similarity index 97%
rename from include/input/NamedEnum.h
rename to include/ftl/NamedEnum.h
index 6562348..f50ff46 100644
--- a/include/input/NamedEnum.h
+++ b/include/ftl/NamedEnum.h
@@ -21,8 +21,7 @@
#include <optional>
#include <string>
-#ifndef __UI_INPUT_NAMEDENUM_H
-#define __UI_INPUT_NAMEDENUM_H
+#pragma once
namespace android {
@@ -124,5 +123,3 @@
};
} // namespace android
-
-#endif // __UI_INPUT_NAMEDENUM_H
\ No newline at end of file
diff --git a/include/ftl/cast.h b/include/ftl/cast.h
new file mode 100644
index 0000000..ff1b58a
--- /dev/null
+++ b/include/ftl/cast.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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 <limits>
+#include <type_traits>
+
+#include <ftl/details/cast.h>
+
+namespace android::ftl {
+
+enum class CastSafety { kSafe, kUnderflow, kOverflow };
+
+// Returns whether static_cast<R>(v) is safe, or would result in underflow or overflow.
+//
+// static_assert(ftl::cast_safety<uint8_t>(-1) == ftl::CastSafety::kUnderflow);
+// static_assert(ftl::cast_safety<int8_t>(128u) == ftl::CastSafety::kOverflow);
+//
+// static_assert(ftl::cast_safety<uint32_t>(-.1f) == ftl::CastSafety::kUnderflow);
+// static_assert(ftl::cast_safety<int32_t>(static_cast<float>(INT32_MAX)) ==
+// ftl::CastSafety::kOverflow);
+//
+// static_assert(ftl::cast_safety<float>(-DBL_MAX) == ftl::CastSafety::kUnderflow);
+//
+template <typename R, typename T>
+constexpr CastSafety cast_safety(T v) {
+ static_assert(std::is_arithmetic_v<T>);
+ static_assert(std::is_arithmetic_v<R>);
+
+ constexpr bool kFromSigned = std::is_signed_v<T>;
+ constexpr bool kToSigned = std::is_signed_v<R>;
+
+ using details::max_exponent;
+
+ // If the R range contains the T range, then casting is always safe.
+ if constexpr ((kFromSigned == kToSigned && max_exponent<R> >= max_exponent<T>) ||
+ (!kFromSigned && kToSigned && max_exponent<R> > max_exponent<T>)) {
+ return CastSafety::kSafe;
+ }
+
+ using C = std::common_type_t<R, T>;
+
+ if constexpr (kFromSigned) {
+ using L = details::safe_limits<R, T>;
+
+ if constexpr (kToSigned) {
+ // Signed to signed.
+ if (v < L::lowest()) return CastSafety::kUnderflow;
+ return v <= L::max() ? CastSafety::kSafe : CastSafety::kOverflow;
+ } else {
+ // Signed to unsigned.
+ if (v < 0) return CastSafety::kUnderflow;
+ return static_cast<C>(v) <= static_cast<C>(L::max()) ? CastSafety::kSafe
+ : CastSafety::kOverflow;
+ }
+ } else {
+ using L = std::numeric_limits<R>;
+
+ if constexpr (kToSigned) {
+ // Unsigned to signed.
+ return static_cast<C>(v) <= static_cast<C>(L::max()) ? CastSafety::kSafe
+ : CastSafety::kOverflow;
+ } else {
+ // Unsigned to unsigned.
+ return v <= L::max() ? CastSafety::kSafe : CastSafety::kOverflow;
+ }
+ }
+}
+
+} // namespace android::ftl
diff --git a/include/ftl/details/cast.h b/include/ftl/details/cast.h
new file mode 100644
index 0000000..87b9f1e
--- /dev/null
+++ b/include/ftl/details/cast.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 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 <limits>
+#include <type_traits>
+
+namespace android::ftl::details {
+
+// Exponent whose power of 2 is the (exclusive) upper bound of T.
+template <typename T, typename L = std::numeric_limits<T>>
+constexpr int max_exponent = std::is_floating_point_v<T> ? L::max_exponent : L::digits;
+
+// Extension of std::numeric_limits<T> that reduces the maximum for integral types T such that it
+// has an exact representation for floating-point types F. For example, the maximum int32_t value
+// is 2'147'483'647, but casting it to float commonly rounds up to 2'147'483'650.f, which cannot
+// be safely converted back lest the signed overflow invokes undefined behavior. This pitfall is
+// avoided by clearing the lower (31 - 24 =) 7 bits of precision to 2'147'483'520. Note that the
+// minimum is representable.
+template <typename T, typename F>
+struct safe_limits : std::numeric_limits<T> {
+ static constexpr T max() {
+ using Base = std::numeric_limits<T>;
+
+ if constexpr (std::is_integral_v<T> && std::is_floating_point_v<F>) {
+ // Assume the mantissa is 24 bits for float, or 53 bits for double.
+ using Float = std::numeric_limits<F>;
+ static_assert(Float::is_iec559);
+
+ // If the integer is wider than the mantissa, clear the excess bits of precision.
+ constexpr int kShift = Base::digits - Float::digits;
+ if constexpr (kShift > 0) {
+ using U = std::make_unsigned_t<T>;
+ constexpr U kOne = static_cast<U>(1);
+ return static_cast<U>(Base::max()) & ~((kOne << kShift) - kOne);
+ }
+ }
+
+ return Base::max();
+ }
+};
+
+} // namespace android::ftl::details
diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h
index 84c15eb..bcaba82 100644
--- a/include/ftl/small_map.h
+++ b/include/ftl/small_map.h
@@ -19,6 +19,7 @@
#include <ftl/initializer_list.h>
#include <ftl/small_vector.h>
+#include <algorithm>
#include <functional>
#include <optional>
#include <type_traits>
@@ -28,7 +29,10 @@
// Associative container with unique, unordered keys. Unlike std::unordered_map, key-value pairs are
// stored in contiguous storage for cache efficiency. The map is allocated statically until its size
-// exceeds N, at which point mappings are relocated to dynamic memory.
+// exceeds N, at which point mappings are relocated to dynamic memory. The try_emplace operation has
+// a non-standard analogue try_replace that destructively emplaces. The API also defines an in-place
+// counterpart to insert_or_assign: emplace_or_replace. Lookup is done not via a subscript operator,
+// but immutable getters that can optionally transform the value.
//
// SmallMap<K, V, 0> unconditionally allocates on the heap.
//
@@ -43,16 +47,19 @@
// assert(!map.dynamic());
//
// assert(map.contains(123));
-// assert(map.find(42, [](const std::string& s) { return s.size(); }) == 3u);
+// assert(map.get(42, [](const std::string& s) { return s.size(); }) == 3u);
//
-// const auto opt = map.find(-1);
+// const auto opt = map.get(-1);
// assert(opt);
//
// std::string& ref = *opt;
// assert(ref.empty());
// ref = "xyz";
//
-// assert(map == SmallMap(ftl::init::map(-1, "xyz")(42, "???")(123, "abc")));
+// map.emplace_or_replace(0, "vanilla", 2u, 3u);
+// assert(map.dynamic());
+//
+// assert(map == SmallMap(ftl::init::map(-1, "xyz")(0, "nil")(42, "???")(123, "abc")));
//
template <typename K, typename V, std::size_t N>
class SmallMap final {
@@ -80,12 +87,7 @@
// The syntax for listing pairs is as follows:
//
// ftl::SmallMap map = ftl::init::map<int, std::string>(123, "abc")(-1)(42, 3u, '?');
- //
// static_assert(std::is_same_v<decltype(map), ftl::SmallMap<int, std::string, 3>>);
- // assert(map.size() == 3u);
- // assert(map.contains(-1) && map.find(-1)->get().empty());
- // assert(map.contains(42) && map.find(42)->get() == "???");
- // assert(map.contains(123) && map.find(123)->get() == "abc");
//
// The types of the key and value are deduced if the first pair contains exactly two arguments:
//
@@ -95,7 +97,7 @@
template <typename U, std::size_t... Sizes, typename... Types>
SmallMap(InitializerList<U, std::index_sequence<Sizes...>, Types...>&& list)
: map_(std::move(list)) {
- // TODO: Enforce unique keys.
+ deduplicate();
}
size_type max_size() const { return map_.max_size(); }
@@ -115,27 +117,27 @@
// Returns whether a mapping exists for the given key.
bool contains(const key_type& key) const {
- return find(key, [](const mapped_type&) {});
+ return get(key, [](const mapped_type&) {});
}
// Returns a reference to the value for the given key, or std::nullopt if the key was not found.
//
// ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
//
- // const auto opt = map.find('c');
+ // const auto opt = map.get('c');
// assert(opt == 'C');
//
// char d = 'd';
- // const auto ref = map.find('d').value_or(std::ref(d));
+ // const auto ref = map.get('d').value_or(std::ref(d));
// ref.get() = 'D';
// assert(d == 'D');
//
- auto find(const key_type& key) const -> std::optional<std::reference_wrapper<const mapped_type>> {
- return find(key, [](const mapped_type& v) { return std::cref(v); });
+ auto get(const key_type& key) const -> std::optional<std::reference_wrapper<const mapped_type>> {
+ return get(key, [](const mapped_type& v) { return std::cref(v); });
}
- auto find(const key_type& key) -> std::optional<std::reference_wrapper<mapped_type>> {
- return find(key, [](mapped_type& v) { return std::ref(v); });
+ auto get(const key_type& key) -> std::optional<std::reference_wrapper<mapped_type>> {
+ return get(key, [](mapped_type& v) { return std::ref(v); });
}
// Returns the result R of a unary operation F on (a constant or mutable reference to) the value
@@ -144,11 +146,11 @@
//
// ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
//
- // assert(map.find('c', [](char c) { return std::toupper(c); }) == 'Z');
- // assert(map.find('c', [](char& c) { c = std::toupper(c); }));
+ // assert(map.get('c', [](char c) { return std::toupper(c); }) == 'Z');
+ // assert(map.get('c', [](char& c) { c = std::toupper(c); }));
//
template <typename F, typename R = std::invoke_result_t<F, const mapped_type&>>
- auto find(const key_type& key, F f) const
+ auto get(const key_type& key, F f) const
-> std::conditional_t<std::is_void_v<R>, bool, std::optional<R>> {
for (auto& [k, v] : *this) {
if (k == key) {
@@ -165,12 +167,96 @@
}
template <typename F>
- auto find(const key_type& key, F f) {
- return std::as_const(*this).find(
+ auto get(const key_type& key, F f) {
+ return std::as_const(*this).get(
key, [&f](const mapped_type& v) { return f(const_cast<mapped_type&>(v)); });
}
+ // Returns an iterator to an existing mapping for the given key, or the end() iterator otherwise.
+ const_iterator find(const key_type& key) const { return const_cast<SmallMap&>(*this).find(key); }
+ iterator find(const key_type& key) { return find(key, begin()); }
+
+ // Inserts a mapping unless it exists. Returns an iterator to the inserted or existing mapping,
+ // and whether the mapping was inserted.
+ //
+ // On emplace, if the map reaches its static or dynamic capacity, then all iterators are
+ // invalidated. Otherwise, only the end() iterator is invalidated.
+ //
+ template <typename... Args>
+ std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) {
+ if (const auto it = find(key); it != end()) {
+ return {it, false};
+ }
+
+ auto& ref = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(std::forward<Args>(args)...));
+ return {&ref, true};
+ }
+
+ // Replaces a mapping if it exists, and returns an iterator to it. Returns the end() iterator
+ // otherwise.
+ //
+ // The value is replaced via move constructor, so type V does not need to define copy/move
+ // assignment, e.g. its data members may be const.
+ //
+ // The arguments may directly or indirectly refer to the mapping being replaced.
+ //
+ // Iterators to the replaced mapping point to its replacement, and others remain valid.
+ //
+ template <typename... Args>
+ iterator try_replace(const key_type& key, Args&&... args) {
+ const auto it = find(key);
+ if (it == end()) return it;
+ map_.replace(it, std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(std::forward<Args>(args)...));
+ return it;
+ }
+
+ // In-place counterpart of std::unordered_map's insert_or_assign. Returns true on emplace, or
+ // false on replace.
+ //
+ // The value is emplaced and replaced via move constructor, so type V does not need to define
+ // copy/move assignment, e.g. its data members may be const.
+ //
+ // On emplace, if the map reaches its static or dynamic capacity, then all iterators are
+ // invalidated. Otherwise, only the end() iterator is invalidated. On replace, iterators
+ // to the replaced mapping point to its replacement, and others remain valid.
+ //
+ template <typename... Args>
+ std::pair<iterator, bool> emplace_or_replace(const key_type& key, Args&&... args) {
+ const auto [it, ok] = try_emplace(key, std::forward<Args>(args)...);
+ if (ok) return {it, ok};
+ map_.replace(it, std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(std::forward<Args>(args)...));
+ return {it, ok};
+ }
+
+ // Removes a mapping if it exists, and returns whether it did.
+ //
+ // The last() and end() iterators, as well as those to the erased mapping, are invalidated.
+ //
+ bool erase(const key_type& key) { return erase(key, begin()); }
+
private:
+ iterator find(const key_type& key, iterator first) {
+ return std::find_if(first, end(), [&key](const auto& pair) { return pair.first == key; });
+ }
+
+ bool erase(const key_type& key, iterator first) {
+ const auto it = find(key, first);
+ if (it == end()) return false;
+ map_.unstable_erase(it);
+ return true;
+ }
+
+ void deduplicate() {
+ for (auto it = begin(); it != end();) {
+ if (const auto key = it->first; ++it != end()) {
+ while (erase(key, it));
+ }
+ }
+ }
+
Map map_;
};
@@ -186,7 +272,7 @@
for (const auto& [k, v] : lhs) {
const auto& lv = v;
- if (!rhs.find(k, [&lv](const auto& rv) { return lv == rv; }).value_or(false)) {
+ if (!rhs.get(k, [&lv](const auto& rv) { return lv == rv; }).value_or(false)) {
return false;
}
}
diff --git a/include/ftl/small_vector.h b/include/ftl/small_vector.h
index cb0ae35..0341435 100644
--- a/include/ftl/small_vector.h
+++ b/include/ftl/small_vector.h
@@ -348,7 +348,7 @@
using Impl::pop_back;
void unstable_erase(iterator it) {
- if (it != last()) std::iter_swap(it, last());
+ if (it != last()) replace(it, std::move(back()));
pop_back();
}
diff --git a/include/ftl/string.h b/include/ftl/string.h
new file mode 100644
index 0000000..2d96b06
--- /dev/null
+++ b/include/ftl/string.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 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 <cassert>
+#include <charconv>
+#include <limits>
+#include <string>
+#include <string_view>
+#include <type_traits>
+
+namespace android::ftl {
+
+enum class Radix { kBin = 2, kDec = 10, kHex = 16 };
+
+template <typename T>
+struct to_chars_length {
+ static_assert(std::is_integral_v<T>);
+ // Maximum binary digits, plus minus sign and radix prefix.
+ static constexpr std::size_t value = std::numeric_limits<std::make_unsigned_t<T>>::digits + 3;
+};
+
+template <typename T>
+constexpr std::size_t to_chars_length_v = to_chars_length<T>::value;
+
+template <typename T = std::int64_t>
+using to_chars_buffer_t = char[to_chars_length_v<T>];
+
+// Lightweight (not allocating nor sprintf-based) alternative to std::to_string for integers, with
+// optional radix. See also ftl::to_string below.
+//
+// ftl::to_chars_buffer_t<> buffer;
+//
+// assert(ftl::to_chars(buffer, 123u) == "123");
+// assert(ftl::to_chars(buffer, -42, ftl::Radix::kBin) == "-0b101010");
+// assert(ftl::to_chars(buffer, 0xcafe, ftl::Radix::kHex) == "0xcafe");
+// assert(ftl::to_chars(buffer, '*', ftl::Radix::kHex) == "0x2a");
+//
+template <typename T, std::size_t N>
+std::string_view to_chars(char (&buffer)[N], T v, Radix radix = Radix::kDec) {
+ static_assert(N >= to_chars_length_v<T>);
+
+ auto begin = buffer + 2;
+ const auto [end, err] = std::to_chars(begin, buffer + N, v, static_cast<int>(radix));
+ assert(err == std::errc());
+
+ if (radix == Radix::kDec) {
+ // TODO: Replace with {begin, end} in C++20.
+ return {begin, static_cast<std::size_t>(end - begin)};
+ }
+
+ const auto prefix = radix == Radix::kBin ? 'b' : 'x';
+ if constexpr (std::is_unsigned_v<T>) {
+ buffer[0] = '0';
+ buffer[1] = prefix;
+ } else {
+ if (*begin == '-') {
+ *buffer = '-';
+ } else {
+ --begin;
+ }
+
+ *begin-- = prefix;
+ *begin = '0';
+ }
+
+ // TODO: Replace with {buffer, end} in C++20.
+ return {buffer, static_cast<std::size_t>(end - buffer)};
+}
+
+// Lightweight (not sprintf-based) alternative to std::to_string for integers, with optional radix.
+//
+// assert(ftl::to_string(123u) == "123");
+// assert(ftl::to_string(-42, ftl::Radix::kBin) == "-0b101010");
+// assert(ftl::to_string(0xcafe, ftl::Radix::kHex) == "0xcafe");
+// assert(ftl::to_string('*', ftl::Radix::kHex) == "0x2a");
+//
+template <typename T>
+inline std::string to_string(T v, Radix radix = Radix::kDec) {
+ to_chars_buffer_t<T> buffer;
+ return std::string(to_chars(buffer, v, radix));
+}
+
+std::string to_string(bool) = delete;
+std::string to_string(bool, Radix) = delete;
+
+} // namespace android::ftl
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
index 5e40ca7..a6213f3 100644
--- a/include/input/DisplayViewport.h
+++ b/include/input/DisplayViewport.h
@@ -18,8 +18,9 @@
#define _LIBINPUT_DISPLAY_VIEWPORT_H
#include <android-base/stringprintf.h>
+#include <ftl/NamedEnum.h>
+#include <gui/constants.h>
#include <input/Input.h>
-#include <input/NamedEnum.h>
#include <cinttypes>
#include <optional>
diff --git a/include/input/Input.h b/include/input/Input.h
index 2e326cb..2e42409 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -124,15 +124,6 @@
constexpr int32_t AMOTION_EVENT_FLAG_CANCELED = 0x20;
enum {
- /* Used when a motion event is not associated with any display.
- * Typically used for non-pointer events. */
- ADISPLAY_ID_NONE = -1,
-
- /* The default display id. */
- ADISPLAY_ID_DEFAULT = 0,
-};
-
-enum {
/*
* Indicates that an input device has switches.
* This input source flag is hidden from the API because switches are only used by the system
@@ -354,12 +345,6 @@
*/
constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN();
-/**
- * Invalid value for display size. Used when display size isn't available for an event or doesn't
- * matter. This is just a constant 0 so that it has no effect if unused.
- */
-constexpr int32_t AMOTION_EVENT_INVALID_DISPLAY_SIZE = 0;
-
/*
* Pointer coordinate data.
*/
@@ -384,8 +369,6 @@
float getAxisValue(int32_t axis) const;
status_t setAxisValue(int32_t axis, float value);
- void scale(float globalScale);
-
// Scale the pointer coordinates according to a global scale and a
// window scale. The global scale will be applied to TOUCH/TOOL_MAJOR/MINOR
// axes, however the window scaling will not.
@@ -592,6 +575,8 @@
void setCursorPosition(float x, float y);
+ uint32_t getDisplayOrientation() const { return mDisplayOrientation; }
+
int2 getDisplaySize() const { return {mDisplayWidth, mDisplayHeight}; }
static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); }
@@ -768,8 +753,8 @@
int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState,
MotionClassification classification, const ui::Transform& transform,
float xPrecision, float yPrecision, float rawXCursorPosition,
- float rawYCursorPosition, int32_t displayWidth, int32_t displayHeight,
- nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
+ float rawYCursorPosition, uint32_t displayOrientation, int32_t displayWidth,
+ int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
void copyFrom(const MotionEvent* other, bool keepHistory);
@@ -827,6 +812,7 @@
float mYPrecision;
float mRawXCursorPosition;
float mRawYCursorPosition;
+ uint32_t mDisplayOrientation;
int32_t mDisplayWidth;
int32_t mDisplayHeight;
nsecs_t mDownTime;
@@ -900,6 +886,25 @@
float mX, mY;
};
+/*
+ * Touch mode events.
+ */
+class TouchModeEvent : public InputEvent {
+public:
+ virtual ~TouchModeEvent() {}
+
+ virtual int32_t getType() const override { return AINPUT_EVENT_TYPE_TOUCH_MODE; }
+
+ inline bool isInTouchMode() const { return mIsInTouchMode; }
+
+ void initialize(int32_t id, bool isInTouchMode);
+
+ void initialize(const TouchModeEvent& from);
+
+protected:
+ bool mIsInTouchMode;
+};
+
/**
* Base class for verified events.
* Do not create a VerifiedInputEvent explicitly.
@@ -964,6 +969,7 @@
virtual FocusEvent* createFocusEvent() = 0;
virtual CaptureEvent* createCaptureEvent() = 0;
virtual DragEvent* createDragEvent() = 0;
+ virtual TouchModeEvent* createTouchModeEvent() = 0;
};
/*
@@ -980,6 +986,7 @@
virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; }
virtual CaptureEvent* createCaptureEvent() override { return &mCaptureEvent; }
virtual DragEvent* createDragEvent() override { return &mDragEvent; }
+ virtual TouchModeEvent* createTouchModeEvent() override { return &mTouchModeEvent; }
private:
KeyEvent mKeyEvent;
@@ -987,6 +994,7 @@
FocusEvent mFocusEvent;
CaptureEvent mCaptureEvent;
DragEvent mDragEvent;
+ TouchModeEvent mTouchModeEvent;
};
/*
@@ -1002,6 +1010,7 @@
virtual FocusEvent* createFocusEvent() override;
virtual CaptureEvent* createCaptureEvent() override;
virtual DragEvent* createDragEvent() override;
+ virtual TouchModeEvent* createTouchModeEvent() override;
void recycle(InputEvent* event);
@@ -1013,6 +1022,7 @@
std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool;
std::queue<std::unique_ptr<CaptureEvent>> mCaptureEventPool;
std::queue<std::unique_ptr<DragEvent>> mDragEventPool;
+ std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEventPool;
};
} // namespace android
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 360dfbf..9a150eb 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -72,6 +72,7 @@
CAPTURE,
DRAG,
TIMELINE,
+ TOUCH_MODE,
};
struct Header {
@@ -136,10 +137,10 @@
float yPrecision;
float xCursorPosition;
float yCursorPosition;
+ uint32_t displayOrientation;
int32_t displayWidth;
int32_t displayHeight;
uint32_t pointerCount;
- uint32_t empty3;
/**
* The "pointers" field must be the last field of the struct InputMessage.
* When we send the struct InputMessage across the socket, we are not
@@ -206,6 +207,15 @@
inline size_t size() const { return sizeof(Timeline); }
} timeline;
+
+ struct TouchMode {
+ int32_t eventId;
+ // The following 2 fields take up 4 bytes total
+ bool isInTouchMode;
+ uint8_t empty[3];
+
+ inline size_t size() const { return sizeof(TouchMode); }
+ } touchMode;
} __attribute__((aligned(8))) body;
bool isValid(size_t actualSize) const;
@@ -355,8 +365,9 @@
int32_t metaState, int32_t buttonState,
MotionClassification classification, const ui::Transform& transform,
float xPrecision, float yPrecision, float xCursorPosition,
- float yCursorPosition, int32_t displayWidth, int32_t displayHeight,
- nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
+ float yCursorPosition, uint32_t displayOrientation,
+ int32_t displayWidth, int32_t displayHeight, nsecs_t downTime,
+ nsecs_t eventTime, uint32_t pointerCount,
const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords);
@@ -387,6 +398,15 @@
*/
status_t publishDragEvent(uint32_t seq, int32_t eventId, float x, float y, bool isExiting);
+ /* Publishes a touch mode event to the input channel.
+ *
+ * Returns OK on success.
+ * Returns WOULD_BLOCK if the channel is full.
+ * Returns DEAD_OBJECT if the channel's peer has been closed.
+ * Other errors probably indicate that the channel is broken.
+ */
+ status_t publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode);
+
struct Finished {
uint32_t seq;
bool handled;
@@ -657,6 +677,7 @@
static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg);
static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg);
static void initializeDragEvent(DragEvent* event, const InputMessage* msg);
+ static void initializeTouchModeEvent(TouchModeEvent* event, const InputMessage* msg);
static void addSample(MotionEvent* event, const InputMessage* msg);
static bool canAddSample(const Batch& batch, const InputMessage* msg);
static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index ec697a0..d7112b5 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -64,10 +64,15 @@
"PermissionCache.cpp",
"PermissionController.cpp",
]
+libbinder_no_vendor_interface_sources = [
+ ":packagemanager_aidl",
+]
cc_library {
name: "libbinder",
+ version_script: "libbinder.map",
+
// for vndbinder
vendor_available: true,
vndk: {
@@ -120,9 +125,8 @@
"Status.cpp",
"TextOutput.cpp",
"Utils.cpp",
- ":packagemanager_aidl",
":libbinder_aidl",
- ],
+ ] + libbinder_no_vendor_interface_sources,
target: {
android: {
@@ -133,40 +137,21 @@
enabled: false,
},
},
- android_arm64: {
- // b/189438896 Sampling PGO restricted to arm64, arm32 in sc-dev
- pgo: {
- sampling: true,
- profile_file: "libbinder/libbinder.profdata",
- },
- // b/189438896 Add exported symbols in a map file for ABI stability
- version_script: "libbinder.arm64.map",
- target: {
- vendor: {
- version_script: "libbinder.arm64.vendor.map",
- },
- },
- },
- android_arm: {
- // b/189438896 Sampling PGO restricted to arm64, arm32 in sc-dev
- pgo: {
- sampling: true,
- profile_file: "libbinder/libbinder.profdata",
- },
- // b/189438896 Add exported symbols in a map file for ABI stability
- version_script: "libbinder.arm32.map",
- target: {
- vendor: {
- version_script: "libbinder.arm32.vendor.map",
- },
- },
- },
vendor: {
- exclude_srcs: libbinder_device_interface_sources,
+ exclude_srcs: libbinder_device_interface_sources + libbinder_no_vendor_interface_sources,
},
darwin: {
enabled: false,
},
+ host: {
+ static_libs: [
+ "libbase",
+ ],
+ srcs: [
+ "ServiceManagerHost.cpp",
+ "UtilsHost.cpp",
+ ],
+ },
},
aidl: {
@@ -190,6 +175,10 @@
binder32bit: {
cflags: ["-DBINDER_IPC_32BIT=1"],
},
+
+ debuggable: {
+ cflags: ["-DBINDER_RPC_DEV_SERVERS"],
+ },
},
shared_libs: [
@@ -200,6 +189,7 @@
header_libs: [
"libbinder_headers",
+ "libandroid_runtime_vm_headers",
],
export_header_lib_headers: [
@@ -232,6 +222,11 @@
"performance*",
"portability*",
],
+
+ pgo: {
+ sampling: true,
+ profile_file: "libbinder/libbinder.profdata",
+ },
}
// AIDL interface between libbinder and framework.jar
@@ -269,6 +264,32 @@
},
}
+// TODO(b/184872979): remove once the Rust API is created.
+cc_library {
+ name: "libbinder_rpc_unstable",
+ srcs: ["libbinder_rpc_unstable.cpp"],
+ defaults: ["libbinder_ndk_host_user"],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libbinder_ndk",
+ "libutils",
+ ],
+
+ // enumerate stable entry points, for apex use
+ stubs: {
+ symbol_file: "libbinder_rpc_unstable.map.txt",
+ },
+
+ // This library is intentionally limited to these targets, and it will be removed later.
+ // Do not expand the visibility.
+ visibility: [
+ "//packages/modules/Virtualization/authfs:__subpackages__",
+ "//packages/modules/Virtualization/compos:__subpackages__",
+ "//packages/modules/Virtualization/microdroid",
+ ],
+}
+
// 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.
@@ -321,3 +342,17 @@
export_aidl_headers: true,
},
}
+
+cc_binary {
+ name: "servicedispatcher",
+ host_supported: false,
+ srcs: [
+ "servicedispatcher.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+}
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index d5bdd1c..628381c 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -17,16 +17,25 @@
#include <binder/Binder.h>
#include <atomic>
-#include <utils/misc.h>
+#include <set>
+
+#include <android-base/unique_fd.h>
#include <binder/BpBinder.h>
#include <binder/IInterface.h>
+#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
#include <binder/IShellCallback.h>
#include <binder/Parcel.h>
+#include <binder/RpcServer.h>
+#include <private/android_filesystem_config.h>
+#include <utils/misc.h>
+#include <inttypes.h>
#include <linux/sched.h>
#include <stdio.h>
+#include "RpcState.h"
+
namespace android {
// Service implementations inherit from BBinder and IBinder, and this is frozen
@@ -39,6 +48,12 @@
static_assert(sizeof(BBinder) == 20);
#endif
+#ifdef BINDER_RPC_DEV_SERVERS
+constexpr const bool kEnableRpcDevServers = true;
+#else
+constexpr const bool kEnableRpcDevServers = false;
+#endif
+
// ---------------------------------------------------------------------------
IBinder::IBinder()
@@ -136,8 +151,79 @@
return OK;
}
+status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd,
+ const sp<IBinder>& keepAliveBinder) {
+ if constexpr (!kEnableRpcDevServers) {
+ ALOGW("setRpcClientDebug disallowed because RPC is not enabled");
+ return INVALID_OPERATION;
+ }
+
+ BBinder* local = this->localBinder();
+ if (local != nullptr) {
+ return local->BBinder::setRpcClientDebug(std::move(socketFd), keepAliveBinder);
+ }
+
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+
+ Parcel data;
+ Parcel reply;
+ status_t status;
+ if (status = data.writeBool(socketFd.ok()); status != OK) return status;
+ if (socketFd.ok()) {
+ // writeUniqueFileDescriptor currently makes an unnecessary dup().
+ status = data.writeFileDescriptor(socketFd.release(), true /* own */);
+ if (status != OK) return status;
+ }
+ if (status = data.writeStrongBinder(keepAliveBinder); status != OK) return status;
+ return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply);
+}
+
+void IBinder::withLock(const std::function<void()>& doWithLock) {
+ BBinder* local = localBinder();
+ if (local) {
+ local->withLock(doWithLock);
+ return;
+ }
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+ proxy->withLock(doWithLock);
+}
+
// ---------------------------------------------------------------------------
+class BBinder::RpcServerLink : public IBinder::DeathRecipient {
+public:
+ // On binder died, calls RpcServer::shutdown on @a rpcServer, and removes itself from @a binder.
+ RpcServerLink(const sp<RpcServer>& rpcServer, const sp<IBinder>& keepAliveBinder,
+ const wp<BBinder>& binder)
+ : mRpcServer(rpcServer), mKeepAliveBinder(keepAliveBinder), mBinder(binder) {}
+ void binderDied(const wp<IBinder>&) override {
+ LOG_RPC_DETAIL("RpcServerLink: binder died, shutting down RpcServer");
+ if (mRpcServer == nullptr) {
+ ALOGW("RpcServerLink: Unable to shut down RpcServer because it does not exist.");
+ } else {
+ ALOGW_IF(!mRpcServer->shutdown(),
+ "RpcServerLink: RpcServer did not shut down properly. Not started?");
+ }
+ mRpcServer.clear();
+
+ auto promoted = mBinder.promote();
+ if (promoted == nullptr) {
+ ALOGW("RpcServerLink: Unable to remove link from parent binder object because parent "
+ "binder object is gone.");
+ } else {
+ promoted->removeRpcServerLink(sp<RpcServerLink>::fromExisting(this));
+ }
+ mBinder.clear();
+ }
+
+private:
+ sp<RpcServer> mRpcServer;
+ sp<IBinder> mKeepAliveBinder; // hold to avoid automatically unlinking
+ wp<BBinder> mBinder;
+};
+
class BBinder::Extras
{
public:
@@ -150,14 +236,13 @@
// for below objects
Mutex mLock;
+ std::set<sp<RpcServerLink>> mRpcServerLinks;
BpBinder::ObjectManager mObjects;
};
// ---------------------------------------------------------------------------
-BBinder::BBinder() : mExtras(nullptr), mStability(0)
-{
-}
+BBinder::BBinder() : mExtras(nullptr), mStability(0), mParceled(false) {}
bool BBinder::isBinderAlive() const
{
@@ -199,6 +284,10 @@
case DEBUG_PID_TRANSACTION:
err = reply->writeInt32(getDebugPid());
break;
+ case SET_RPC_CLIENT_TRANSACTION: {
+ err = setRpcClientDebug(data);
+ break;
+ }
default:
err = onTransact(code, data, reply, flags);
break;
@@ -233,15 +322,13 @@
return NO_ERROR;
}
-void BBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
+void* BBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
+ object_cleanup_func func) {
Extras* e = getOrCreateExtras();
- if (!e) return; // out of memory
+ LOG_ALWAYS_FATAL_IF(!e, "no memory");
AutoMutex _l(e->mLock);
- e->mObjects.attach(objectID, object, cleanupCookie, func);
+ return e->mObjects.attach(objectID, object, cleanupCookie, func);
}
void* BBinder::findObject(const void* objectID) const
@@ -253,13 +340,20 @@
return e->mObjects.find(objectID);
}
-void BBinder::detachObject(const void* objectID)
-{
+void* BBinder::detachObject(const void* objectID) {
Extras* e = mExtras.load(std::memory_order_acquire);
- if (!e) return;
+ if (!e) return nullptr;
AutoMutex _l(e->mLock);
- e->mObjects.detach(objectID);
+ return e->mObjects.detach(objectID);
+}
+
+void BBinder::withLock(const std::function<void()>& doWithLock) {
+ Extras* e = getOrCreateExtras();
+ LOG_ALWAYS_FATAL_IF(!e, "no memory");
+
+ AutoMutex _l(e->mLock);
+ doWithLock();
}
BBinder* BBinder::localBinder()
@@ -276,6 +370,10 @@
void BBinder::setRequestingSid(bool requestingSid)
{
+ LOG_ALWAYS_FATAL_IF(mParceled,
+ "setRequestingSid() should not be called after a binder object "
+ "is parceled/sent to another process");
+
Extras* e = mExtras.load(std::memory_order_acquire);
if (!e) {
@@ -298,6 +396,10 @@
}
void BBinder::setMinSchedulerPolicy(int policy, int priority) {
+ LOG_ALWAYS_FATAL_IF(mParceled,
+ "setMinSchedulerPolicy() should not be called after a binder object "
+ "is parceled/sent to another process");
+
switch (policy) {
case SCHED_NORMAL:
LOG_ALWAYS_FATAL_IF(priority < -20 || priority > 19, "Invalid priority for SCHED_NORMAL: %d", priority);
@@ -345,6 +447,10 @@
}
void BBinder::setInheritRt(bool inheritRt) {
+ LOG_ALWAYS_FATAL_IF(mParceled,
+ "setInheritRt() should not be called after a binder object "
+ "is parceled/sent to another process");
+
Extras* e = mExtras.load(std::memory_order_acquire);
if (!e) {
@@ -364,10 +470,106 @@
}
void BBinder::setExtension(const sp<IBinder>& extension) {
+ LOG_ALWAYS_FATAL_IF(mParceled,
+ "setExtension() should not be called after a binder object "
+ "is parceled/sent to another process");
+
Extras* e = getOrCreateExtras();
e->mExtension = extension;
}
+bool BBinder::wasParceled() {
+ return mParceled;
+}
+
+void BBinder::setParceled() {
+ mParceled = true;
+}
+
+status_t BBinder::setRpcClientDebug(const Parcel& data) {
+ if constexpr (!kEnableRpcDevServers) {
+ ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+ if (uid != AID_ROOT) {
+ ALOGE("%s: not allowed because client %" PRIu32 " is not root", __PRETTY_FUNCTION__, uid);
+ return PERMISSION_DENIED;
+ }
+ status_t status;
+ bool hasSocketFd;
+ android::base::unique_fd clientFd;
+
+ if (status = data.readBool(&hasSocketFd); status != OK) return status;
+ if (hasSocketFd) {
+ if (status = data.readUniqueFileDescriptor(&clientFd); status != OK) return status;
+ }
+ sp<IBinder> keepAliveBinder;
+ if (status = data.readNullableStrongBinder(&keepAliveBinder); status != OK) return status;
+
+ return setRpcClientDebug(std::move(clientFd), keepAliveBinder);
+}
+
+status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd,
+ const sp<IBinder>& keepAliveBinder) {
+ if constexpr (!kEnableRpcDevServers) {
+ ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ const int socketFdForPrint = socketFd.get();
+ LOG_RPC_DETAIL("%s(fd=%d)", __PRETTY_FUNCTION__, socketFdForPrint);
+
+ if (!socketFd.ok()) {
+ ALOGE("%s: No socket FD provided.", __PRETTY_FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ if (keepAliveBinder == nullptr) {
+ ALOGE("%s: No keepAliveBinder provided.", __PRETTY_FUNCTION__);
+ return UNEXPECTED_NULL;
+ }
+
+ size_t binderThreadPoolMaxCount = ProcessState::self()->getThreadPoolMaxThreadCount();
+ if (binderThreadPoolMaxCount <= 1) {
+ ALOGE("%s: ProcessState thread pool max count is %zu. RPC is disabled for this service "
+ "because RPC requires the service to support multithreading.",
+ __PRETTY_FUNCTION__, binderThreadPoolMaxCount);
+ return INVALID_OPERATION;
+ }
+
+ // Weak ref to avoid circular dependency:
+ // BBinder -> RpcServerLink ----> RpcServer -X-> BBinder
+ // `-X-> BBinder
+ auto weakThis = wp<BBinder>::fromExisting(this);
+
+ Extras* e = getOrCreateExtras();
+ AutoMutex _l(e->mLock);
+ auto rpcServer = RpcServer::make();
+ LOG_ALWAYS_FATAL_IF(rpcServer == nullptr, "RpcServer::make returns null");
+ rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ auto link = sp<RpcServerLink>::make(rpcServer, keepAliveBinder, weakThis);
+ if (auto status = keepAliveBinder->linkToDeath(link, nullptr, 0); status != OK) {
+ ALOGE("%s: keepAliveBinder->linkToDeath returns %s", __PRETTY_FUNCTION__,
+ statusToString(status).c_str());
+ return status;
+ }
+ rpcServer->setRootObjectWeak(weakThis);
+ rpcServer->setupExternalServer(std::move(socketFd));
+ rpcServer->setMaxThreads(binderThreadPoolMaxCount);
+ rpcServer->start();
+ e->mRpcServerLinks.emplace(link);
+ LOG_RPC_DETAIL("%s(fd=%d) successful", __PRETTY_FUNCTION__, socketFdForPrint);
+ return OK;
+}
+
+void BBinder::removeRpcServerLink(const sp<RpcServerLink>& link) {
+ Extras* e = mExtras.load(std::memory_order_acquire);
+ if (!e) return;
+ AutoMutex _l(e->mLock);
+ (void)e->mRpcServerLinks.erase(link);
+}
+
BBinder::~BBinder()
{
Extras* e = mExtras.load(std::memory_order_relaxed);
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 1dcb94c..3099296 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -61,22 +61,22 @@
kill();
}
-void BpBinder::ObjectManager::attach(
- const void* objectID, void* object, void* cleanupCookie,
- IBinder::object_cleanup_func func)
-{
+void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie,
+ IBinder::object_cleanup_func func) {
entry_t e;
e.object = object;
e.cleanupCookie = cleanupCookie;
e.func = func;
- if (mObjects.indexOfKey(objectID) >= 0) {
- ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
- objectID, this, object);
- return;
+ if (ssize_t idx = mObjects.indexOfKey(objectID); idx >= 0) {
+ ALOGI("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object "
+ "ID already in use",
+ objectID, this, object);
+ return mObjects[idx].object;
}
mObjects.add(objectID, e);
+ return nullptr;
}
void* BpBinder::ObjectManager::find(const void* objectID) const
@@ -86,9 +86,12 @@
return mObjects.valueAt(i).object;
}
-void BpBinder::ObjectManager::detach(const void* objectID)
-{
- mObjects.removeItem(objectID);
+void* BpBinder::ObjectManager::detach(const void* objectID) {
+ ssize_t idx = mObjects.indexOfKey(objectID);
+ if (idx < 0) return nullptr;
+ void* value = mObjects[idx].object;
+ mObjects.removeItemsAt(idx, 1);
+ return value;
}
void BpBinder::ObjectManager::kill()
@@ -273,7 +276,8 @@
status_t status;
if (CC_UNLIKELY(isRpcBinder())) {
- status = rpcSession()->transact(rpcAddress(), code, data, reply, flags);
+ status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data, reply,
+ flags);
} else {
status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
}
@@ -405,14 +409,11 @@
recipient->binderDied(wp<BpBinder>::fromExisting(this));
}
-
-void BpBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
+void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
+ object_cleanup_func func) {
AutoMutex _l(mLock);
ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
- mObjects.attach(objectID, object, cleanupCookie, func);
+ return mObjects.attach(objectID, object, cleanupCookie, func);
}
void* BpBinder::findObject(const void* objectID) const
@@ -421,10 +422,14 @@
return mObjects.find(objectID);
}
-void BpBinder::detachObject(const void* objectID)
-{
+void* BpBinder::detachObject(const void* objectID) {
AutoMutex _l(mLock);
- mObjects.detach(objectID);
+ return mObjects.detach(objectID);
+}
+
+void BpBinder::withLock(const std::function<void()>& doWithLock) {
+ AutoMutex _l(mLock);
+ doWithLock();
}
BpBinder* BpBinder::remoteBinder()
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 445df9e..fa9f3a9 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -366,19 +366,46 @@
pid_t IPCThreadState::getCallingPid() const
{
+ checkContextIsBinderForUse(__func__);
return mCallingPid;
}
const char* IPCThreadState::getCallingSid() const
{
+ checkContextIsBinderForUse(__func__);
return mCallingSid;
}
uid_t IPCThreadState::getCallingUid() const
{
+ checkContextIsBinderForUse(__func__);
return mCallingUid;
}
+const IPCThreadState::SpGuard* IPCThreadState::pushGetCallingSpGuard(const SpGuard* guard) {
+ const SpGuard* orig = mServingStackPointerGuard;
+ mServingStackPointerGuard = guard;
+ return orig;
+}
+
+void IPCThreadState::restoreGetCallingSpGuard(const SpGuard* guard) {
+ mServingStackPointerGuard = guard;
+}
+
+void IPCThreadState::checkContextIsBinderForUse(const char* use) const {
+ if (LIKELY(mServingStackPointerGuard == nullptr)) return;
+
+ if (!mServingStackPointer || mServingStackPointerGuard->address < mServingStackPointer) {
+ LOG_ALWAYS_FATAL("In context %s, %s does not make sense (binder sp: %p, guard: %p).",
+ mServingStackPointerGuard->context, use, mServingStackPointer,
+ mServingStackPointerGuard->address);
+ }
+
+ // in the case mServingStackPointer is deeper in the stack than the guard,
+ // we must be serving a binder transaction (maybe nested). This is a binder
+ // context, so we don't abort
+}
+
int64_t IPCThreadState::clearCallingIdentity()
{
// ignore mCallingSid for legacy reasons
@@ -845,6 +872,7 @@
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mServingStackPointer(nullptr),
+ mServingStackPointerGuard(nullptr),
mWorkSource(kUnsetWorkSource),
mPropagateWorkSource(false),
mIsLooper(false),
@@ -1226,7 +1254,7 @@
tr.offsets_size/sizeof(binder_size_t), freeBuffer);
const void* origServingStackPointer = mServingStackPointer;
- mServingStackPointer = &origServingStackPointer; // anything on the stack
+ mServingStackPointer = __builtin_frame_address(0);
const pid_t origPid = mCallingPid;
const char* origSid = mCallingSid;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index f684cf6..2175fd4 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -35,6 +35,8 @@
#ifdef __ANDROID__
#include <cutils/properties.h>
+#else
+#include "ServiceManagerHost.h"
#endif
#include "Static.h"
@@ -84,8 +86,19 @@
IBinder* onAsBinder() override {
return IInterface::asBinder(mTheRealServiceManager).get();
}
-private:
+
+protected:
sp<AidlServiceManager> mTheRealServiceManager;
+
+ // Directly get the service in a way that, for lazy services, requests the service to be started
+ // if it is not currently started. This way, calls directly to ServiceManagerShim::getService
+ // will still have the 5s delay that is expected by a large amount of Android code.
+ //
+ // When implementing ServiceManagerShim, use realGetService instead of
+ // mTheRealServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
+ virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+ return mTheRealServiceManager->getService(name, _aidl_return);
+ }
};
[[clang::no_destroy]] static std::once_flag gSmOnce;
@@ -129,8 +142,7 @@
return checkCallingPermission(permission, nullptr, nullptr);
}
-static String16 _permission("permission");
-
+static StaticString16 _permission(u"permission");
bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
{
@@ -320,14 +332,18 @@
const std::string name = String8(name16).c_str();
sp<IBinder> out;
- if (!mTheRealServiceManager->getService(name, &out).isOk()) {
+ if (Status status = realGetService(name, &out); !status.isOk()) {
+ ALOGW("Failed to getService in waitForService for %s: %s", name.c_str(),
+ status.toString8().c_str());
return nullptr;
}
if (out != nullptr) return out;
sp<Waiter> waiter = sp<Waiter>::make();
- if (!mTheRealServiceManager->registerForNotifications(
- name, waiter).isOk()) {
+ if (Status status = mTheRealServiceManager->registerForNotifications(name, waiter);
+ !status.isOk()) {
+ ALOGW("Failed to registerForNotifications in waitForService for %s: %s", name.c_str(),
+ status.toString8().c_str());
return nullptr;
}
Defer unregister ([&] {
@@ -360,7 +376,9 @@
// - init gets death signal, but doesn't know it needs to restart
// the service
// - we need to request service again to get it to start
- if (!mTheRealServiceManager->getService(name, &out).isOk()) {
+ if (Status status = realGetService(name, &out); !status.isOk()) {
+ ALOGW("Failed to getService in waitForService on later try for %s: %s", name.c_str(),
+ status.toString8().c_str());
return nullptr;
}
if (out != nullptr) return out;
@@ -369,7 +387,10 @@
bool ServiceManagerShim::isDeclared(const String16& name) {
bool declared;
- if (!mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared).isOk()) {
+ if (Status status = mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared);
+ !status.isOk()) {
+ ALOGW("Failed to get isDeclard for %s: %s", String8(name).c_str(),
+ status.toString8().c_str());
return false;
}
return declared;
@@ -377,7 +398,11 @@
Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interface) {
std::vector<std::string> out;
- if (!mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out).isOk()) {
+ if (Status status =
+ mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
+ !status.isOk()) {
+ ALOGW("Failed to getDeclaredInstances for %s: %s", String8(interface).c_str(),
+ status.toString8().c_str());
return {};
}
@@ -391,10 +416,47 @@
std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& name) {
std::optional<std::string> declared;
- if (!mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared).isOk()) {
+ if (Status status = mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared);
+ !status.isOk()) {
+ ALOGW("Failed to get updatableViaApex for %s: %s", String8(name).c_str(),
+ status.toString8().c_str());
return std::nullopt;
}
return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
}
+#ifndef __ANDROID__
+// ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API.
+// The internal implementation of the AIDL interface android::os::IServiceManager calls into
+// on-device service manager.
+class ServiceManagerHostShim : public ServiceManagerShim {
+public:
+ using ServiceManagerShim::ServiceManagerShim;
+ // ServiceManagerShim::getService is based on checkService, so no need to override it.
+ sp<IBinder> checkService(const String16& name) const override {
+ return getDeviceService({String8(name).c_str()});
+ }
+
+protected:
+ // Override realGetService for ServiceManagerShim::waitForService.
+ Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+ *_aidl_return = getDeviceService({"-g", name});
+ return Status::ok();
+ }
+};
+sp<IServiceManager> createRpcDelegateServiceManager() {
+ auto binder = getDeviceService({"manager"});
+ if (binder == nullptr) {
+ ALOGE("getDeviceService(\"manager\") returns null");
+ return nullptr;
+ }
+ auto interface = AidlServiceManager::asInterface(binder);
+ if (interface == nullptr) {
+ ALOGE("getDeviceService(\"manager\") returns non service manager");
+ return nullptr;
+ }
+ return sp<ServiceManagerHostShim>::make(interface);
+}
+#endif
+
} // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index ee834ea..a2ac96e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -173,8 +173,8 @@
status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder)
{
internal::Stability::tryMarkCompilationUnit(binder.get());
- auto category = internal::Stability::getCategory(binder.get());
- return writeInt32(category.repr());
+ int16_t rep = internal::Stability::getCategory(binder.get()).repr();
+ return writeInt32(rep);
}
status_t Parcel::finishUnflattenBinder(
@@ -184,7 +184,8 @@
status_t status = readInt32(&stability);
if (status != OK) return status;
- status = internal::Stability::setRepr(binder.get(), stability, true /*log*/);
+ status = internal::Stability::setRepr(binder.get(), static_cast<int16_t>(stability),
+ true /*log*/);
if (status != OK) return status;
*out = binder;
@@ -195,13 +196,17 @@
return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
}
-status_t Parcel::flattenBinder(const sp<IBinder>& binder)
-{
+status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
+ BBinder* local = nullptr;
+ if (binder) local = binder->localBinder();
+ if (local) local->setParceled();
+
if (isForRpc()) {
if (binder) {
status_t status = writeInt32(1); // non-null
if (status != OK) return status;
RpcAddress address = RpcAddress::zero();
+ // TODO(b/167966510): need to undo this if the Parcel is not sent
status = mSession->state()->onBinderLeaving(mSession, binder, &address);
if (status != OK) return status;
status = address.writeToParcel(this);
@@ -222,7 +227,6 @@
}
if (binder != nullptr) {
- BBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == nullptr) {
@@ -283,9 +287,10 @@
if (isNull & 1) {
auto addr = RpcAddress::zero();
- status_t status = addr.readFromParcel(*this);
- if (status != OK) return status;
- binder = mSession->state()->onBinderEntering(mSession, addr);
+ if (status_t status = addr.readFromParcel(*this); status != OK) return status;
+ if (status_t status = mSession->state()->onBinderEntering(mSession, addr, &binder);
+ status != OK)
+ return status;
}
return finishUnflattenBinder(binder, out);
@@ -1466,6 +1471,29 @@
return nullptr;
}
+status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const {
+ if (status_t status = readInt32(size); status != OK) return status;
+ if (*size < 0) return OK; // may be null, client to handle
+
+ LOG_ALWAYS_FATAL_IF(elmSize > INT32_MAX, "Cannot have element as big as %zu", elmSize);
+
+ // approximation, can't know max element size (e.g. if it makes heap
+ // allocations)
+ static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64");
+ int32_t allocationSize;
+ if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY;
+
+ // High limit of 1MB since something this big could never be returned. Could
+ // probably scope this down, but might impact very specific usecases.
+ constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000;
+
+ if (allocationSize >= kMaxAllocationSize) {
+ return NO_MEMORY;
+ }
+
+ return OK;
+}
+
template<class T>
status_t Parcel::readAligned(T *pArg) const {
static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index bade918..650a108 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -359,6 +359,14 @@
return result;
}
+size_t ProcessState::getThreadPoolMaxThreadCount() const {
+ // may actually be one more than this, if join is called
+ if (mThreadPoolStarted) return mMaxThreads;
+ // must not be initialized or maybe has poll thread setup, we
+ // currently don't track this in libbinder
+ return 0;
+}
+
status_t ProcessState::enableOnewaySpamDetection(bool enable) {
uint32_t enableDetection = enable ? 1 : 0;
if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) {
diff --git a/libs/binder/RpcAddress.cpp b/libs/binder/RpcAddress.cpp
index 5c32320..98dee9a 100644
--- a/libs/binder/RpcAddress.cpp
+++ b/libs/binder/RpcAddress.cpp
@@ -29,7 +29,7 @@
}
bool RpcAddress::isZero() const {
- RpcWireAddress ZERO{0};
+ RpcWireAddress ZERO{.options = 0};
return memcmp(mRawAddr.get(), &ZERO, sizeof(RpcWireAddress)) == 0;
}
@@ -51,13 +51,34 @@
close(fd);
}
-RpcAddress RpcAddress::unique() {
+RpcAddress RpcAddress::random(bool forServer) {
+ // The remainder of this header acts as reserved space for different kinds
+ // of binder objects.
+ uint64_t options = RPC_WIRE_ADDRESS_OPTION_CREATED;
+
+ // servers and clients allocate addresses independently, so this bit can
+ // tell you where an address originates
+ if (forServer) options |= RPC_WIRE_ADDRESS_OPTION_FOR_SERVER;
+
RpcAddress ret;
- ReadRandomBytes((uint8_t*)ret.mRawAddr.get(), sizeof(RpcWireAddress));
+ RpcWireAddress* raw = ret.mRawAddr.get();
+
+ raw->options = options;
+ ReadRandomBytes(raw->address, sizeof(raw->address));
+
LOG_RPC_DETAIL("Creating new address: %s", ret.toString().c_str());
return ret;
}
+bool RpcAddress::isForServer() const {
+ return mRawAddr.get()->options & RPC_WIRE_ADDRESS_OPTION_FOR_SERVER;
+}
+
+bool RpcAddress::isRecognizedType() const {
+ uint64_t allKnownOptions = RPC_WIRE_ADDRESS_OPTION_CREATED | RPC_WIRE_ADDRESS_OPTION_FOR_SERVER;
+ return (mRawAddr.get()->options & ~allKnownOptions) == 0;
+}
+
RpcAddress RpcAddress::fromRawEmbedded(const RpcWireAddress* raw) {
RpcAddress addr;
memcpy(addr.mRawAddr.get(), raw, sizeof(RpcWireAddress));
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 9cc6e7f..c6cf2c5 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "RpcServer"
+#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -26,9 +27,9 @@
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <log/log.h>
-#include "RpcState.h"
#include "RpcSocketAddress.h"
+#include "RpcState.h"
#include "RpcWireFormat.h"
namespace android {
@@ -37,7 +38,9 @@
using base::unique_fd;
RpcServer::RpcServer() {}
-RpcServer::~RpcServer() {}
+RpcServer::~RpcServer() {
+ (void)shutdown();
+}
sp<RpcServer> RpcServer::make() {
return sp<RpcServer>::make();
@@ -99,7 +102,7 @@
void RpcServer::setMaxThreads(size_t threads) {
LOG_ALWAYS_FATAL_IF(threads <= 0, "RpcServer is useless without threads");
- LOG_ALWAYS_FATAL_IF(mStarted, "must be called before started");
+ LOG_ALWAYS_FATAL_IF(mJoinThreadRunning, "Cannot set max threads while running");
mMaxThreads = threads;
}
@@ -126,33 +129,93 @@
return ret;
}
-void RpcServer::join() {
- while (true) {
- (void)acceptOne();
- }
+static void joinRpcServer(sp<RpcServer>&& thiz) {
+ thiz->join();
}
-bool RpcServer::acceptOne() {
+void RpcServer::start() {
LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
- LOG_ALWAYS_FATAL_IF(!hasServer(), "RpcServer must be setup to join.");
+ std::lock_guard<std::mutex> _l(mLock);
+ LOG_ALWAYS_FATAL_IF(mJoinThread.get(), "Already started!");
+ mJoinThread = std::make_unique<std::thread>(&joinRpcServer, sp<RpcServer>::fromExisting(this));
+}
- unique_fd clientFd(
- TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
-
- if (clientFd < 0) {
- ALOGE("Could not accept4 socket: %s", strerror(errno));
- return false;
- }
- LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+void RpcServer::join() {
+ LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
{
std::lock_guard<std::mutex> _l(mLock);
- std::thread thread =
- std::thread(&RpcServer::establishConnection, this,
- std::move(sp<RpcServer>::fromExisting(this)), std::move(clientFd));
- mConnectingThreads[thread.get_id()] = std::move(thread);
+ LOG_ALWAYS_FATAL_IF(!mServer.ok(), "RpcServer must be setup to join.");
+ LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr, "Already joined");
+ mJoinThreadRunning = true;
+ mShutdownTrigger = RpcSession::FdTrigger::make();
+ LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr, "Cannot create join signaler");
}
+ status_t status;
+ while ((status = mShutdownTrigger->triggerablePoll(mServer, POLLIN)) == OK) {
+ unique_fd clientFd(TEMP_FAILURE_RETRY(
+ accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
+
+ if (clientFd < 0) {
+ ALOGE("Could not accept4 socket: %s", strerror(errno));
+ continue;
+ }
+ LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+
+ {
+ std::lock_guard<std::mutex> _l(mLock);
+ std::thread thread =
+ std::thread(&RpcServer::establishConnection, sp<RpcServer>::fromExisting(this),
+ std::move(clientFd));
+ mConnectingThreads[thread.get_id()] = std::move(thread);
+ }
+ }
+ LOG_RPC_DETAIL("RpcServer::join exiting with %s", statusToString(status).c_str());
+
+ {
+ std::lock_guard<std::mutex> _l(mLock);
+ mJoinThreadRunning = false;
+ }
+ mShutdownCv.notify_all();
+}
+
+bool RpcServer::shutdown() {
+ std::unique_lock<std::mutex> _l(mLock);
+ if (mShutdownTrigger == nullptr) {
+ LOG_RPC_DETAIL("Cannot shutdown. No shutdown trigger installed (already shutdown?)");
+ return false;
+ }
+
+ mShutdownTrigger->trigger();
+ for (auto& [id, session] : mSessions) {
+ (void)id;
+ session->mShutdownTrigger->trigger();
+ }
+
+ while (mJoinThreadRunning || !mConnectingThreads.empty() || !mSessions.empty()) {
+ if (std::cv_status::timeout == mShutdownCv.wait_for(_l, std::chrono::seconds(1))) {
+ ALOGE("Waiting for RpcServer to shut down (1s w/o progress). Join thread running: %d, "
+ "Connecting threads: "
+ "%zu, Sessions: %zu. Is your server deadlocked?",
+ mJoinThreadRunning, mConnectingThreads.size(), mSessions.size());
+ }
+ }
+
+ // At this point, we know join() is about to exit, but the thread that calls
+ // join() may not have exited yet.
+ // If RpcServer owns the join thread (aka start() is called), make sure the thread exits;
+ // otherwise ~thread() may call std::terminate(), which may crash the process.
+ // If RpcServer does not own the join thread (aka join() is called directly),
+ // then the owner of RpcServer is responsible for cleaning up that thread.
+ if (mJoinThread.get()) {
+ mJoinThread->join();
+ mJoinThread.reset();
+ }
+
+ LOG_RPC_DETAIL("Finished waiting on shutdown.");
+
+ mShutdownTrigger = nullptr;
return true;
}
@@ -172,62 +235,102 @@
}
void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd) {
- LOG_ALWAYS_FATAL_IF(this != server.get(), "Must pass same ownership object");
-
// TODO(b/183988761): cannot trust this simple ID
- LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
- bool idValid = true;
- int32_t id;
- if (sizeof(id) != read(clientFd.get(), &id, sizeof(id))) {
- ALOGE("Could not read ID from fd %d", clientFd.get());
- idValid = false;
+ LOG_ALWAYS_FATAL_IF(!server->mAgreedExperimental, "no!");
+
+ // mShutdownTrigger can only be cleared once connection threads have joined.
+ // It must be set before this thread is started
+ LOG_ALWAYS_FATAL_IF(server->mShutdownTrigger == nullptr);
+
+ RpcConnectionHeader header;
+ status_t status = server->mShutdownTrigger->interruptableReadFully(clientFd.get(), &header,
+ sizeof(header));
+ bool idValid = status == OK;
+ if (!idValid) {
+ ALOGE("Failed to read ID for client connecting to RPC server: %s",
+ statusToString(status).c_str());
+ // still need to cleanup before we can return
}
+ bool incoming = header.options & RPC_CONNECTION_OPTION_INCOMING;
std::thread thisThread;
sp<RpcSession> session;
{
- std::lock_guard<std::mutex> _l(mLock);
+ std::unique_lock<std::mutex> _l(server->mLock);
- auto threadId = mConnectingThreads.find(std::this_thread::get_id());
- LOG_ALWAYS_FATAL_IF(threadId == mConnectingThreads.end(),
+ auto threadId = server->mConnectingThreads.find(std::this_thread::get_id());
+ LOG_ALWAYS_FATAL_IF(threadId == server->mConnectingThreads.end(),
"Must establish connection on owned thread");
thisThread = std::move(threadId->second);
- ScopeGuard detachGuard = [&]() { thisThread.detach(); };
- mConnectingThreads.erase(threadId);
+ ScopeGuard detachGuard = [&]() {
+ thisThread.detach();
+ _l.unlock();
+ server->mShutdownCv.notify_all();
+ };
+ server->mConnectingThreads.erase(threadId);
- if (!idValid) {
+ if (!idValid || server->mShutdownTrigger->isTriggered()) {
return;
}
- if (id == RPC_SESSION_ID_NEW) {
- LOG_ALWAYS_FATAL_IF(mSessionIdCounter >= INT32_MAX, "Out of session IDs");
- mSessionIdCounter++;
+ RpcAddress sessionId = RpcAddress::fromRawEmbedded(&header.sessionId);
+
+ if (sessionId.isZero()) {
+ if (incoming) {
+ ALOGE("Cannot create a new session with an incoming connection, would leak");
+ return;
+ }
+
+ sessionId = RpcAddress::zero();
+ size_t tries = 0;
+ do {
+ // don't block if there is some entropy issue
+ if (tries++ > 5) {
+ ALOGE("Cannot find new address: %s", sessionId.toString().c_str());
+ return;
+ }
+
+ sessionId = RpcAddress::random(true /*forServer*/);
+ } while (server->mSessions.end() != server->mSessions.find(sessionId));
session = RpcSession::make();
- session->setForServer(wp<RpcServer>::fromExisting(this), mSessionIdCounter);
+ session->setMaxThreads(server->mMaxThreads);
+ if (!session->setForServer(server,
+ sp<RpcServer::EventListener>::fromExisting(
+ static_cast<RpcServer::EventListener*>(
+ server.get())),
+ sessionId)) {
+ ALOGE("Failed to attach server to session");
+ return;
+ }
- mSessions[mSessionIdCounter] = session;
+ server->mSessions[sessionId] = session;
} else {
- auto it = mSessions.find(id);
- if (it == mSessions.end()) {
- ALOGE("Cannot add thread, no record of session with ID %d", id);
+ auto it = server->mSessions.find(sessionId);
+ if (it == server->mSessions.end()) {
+ ALOGE("Cannot add thread, no record of session with ID %s",
+ sessionId.toString().c_str());
return;
}
session = it->second;
}
+ if (incoming) {
+ LOG_ALWAYS_FATAL_IF(!session->addOutgoingConnection(std::move(clientFd), true),
+ "server state must already be initialized");
+ return;
+ }
+
detachGuard.Disable();
- session->preJoin(std::move(thisThread));
+ session->preJoinThreadOwnership(std::move(thisThread));
}
+ auto setupResult = session->preJoinSetup(std::move(clientFd));
+
// avoid strong cycle
server = nullptr;
- //
- //
- // DO NOT ACCESS MEMBER VARIABLES BELOW
- //
- session->join(std::move(clientFd));
+ RpcSession::join(std::move(session), std::move(setupResult));
}
bool RpcServer::setupSocketServer(const RpcSocketAddress& addr) {
@@ -247,7 +350,11 @@
return false;
}
- if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
+ // Right now, we create all threads at once, making accept4 slow. To avoid hanging the client,
+ // the backlog is increased to a large number.
+ // TODO(b/189955605): Once we create threads dynamically & lazily, the backlog can be reduced
+ // to 1.
+ if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 50 /*backlog*/))) {
int savedErrno = errno;
ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
return false;
@@ -255,22 +362,31 @@
LOG_RPC_DETAIL("Successfully setup socket server %s", addr.toString().c_str());
- mServer = std::move(serverFd);
+ if (!setupExternalServer(std::move(serverFd))) {
+ ALOGE("Another thread has set up server while calling setupSocketServer. Race?");
+ return false;
+ }
return true;
}
-void RpcServer::onSessionTerminating(const sp<RpcSession>& session) {
+void RpcServer::onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) {
auto id = session->mId;
LOG_ALWAYS_FATAL_IF(id == std::nullopt, "Server sessions must be initialized with ID");
- LOG_RPC_DETAIL("Dropping session %d", *id);
+ LOG_RPC_DETAIL("Dropping session with address %s", id->toString().c_str());
std::lock_guard<std::mutex> _l(mLock);
auto it = mSessions.find(*id);
- LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %d", *id);
- LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %d", *id);
+ LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %s",
+ id->toString().c_str());
+ LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %s",
+ id->toString().c_str());
(void)mSessions.erase(it);
}
+void RpcServer::onSessionIncomingThreadEnded() {
+ mShutdownCv.notify_all();
+}
+
bool RpcServer::hasServer() {
LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
std::lock_guard<std::mutex> _l(mLock);
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 05fa49e..5fe0b00 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -18,14 +18,20 @@
#include <binder/RpcSession.h>
+#include <dlfcn.h>
#include <inttypes.h>
+#include <poll.h>
+#include <pthread.h>
#include <unistd.h>
#include <string_view>
+#include <android-base/macros.h>
+#include <android_runtime/vm.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/Stability.h>
+#include <jni.h>
#include <utils/String8.h>
#include "RpcSocketAddress.h"
@@ -49,7 +55,7 @@
LOG_RPC_DETAIL("RpcSession destroyed %p", this);
std::lock_guard<std::mutex> _l(mMutex);
- LOG_ALWAYS_FATAL_IF(mServerConnections.size() != 0,
+ LOG_ALWAYS_FATAL_IF(mIncomingConnections.size() != 0,
"Should not be able to destroy a session with servers in use.");
}
@@ -57,6 +63,20 @@
return sp<RpcSession>::make();
}
+void RpcSession::setMaxThreads(size_t threads) {
+ std::lock_guard<std::mutex> _l(mMutex);
+ LOG_ALWAYS_FATAL_IF(!mOutgoingConnections.empty() || !mIncomingConnections.empty(),
+ "Must set max threads before setting up connections, but has %zu client(s) "
+ "and %zu server(s)",
+ mOutgoingConnections.size(), mIncomingConnections.size());
+ mMaxThreads = threads;
+}
+
+size_t RpcSession::getMaxThreads() {
+ std::lock_guard<std::mutex> _l(mMutex);
+ return mMaxThreads;
+}
+
bool RpcSession::setupUnixDomainClient(const char* path) {
return setupSocketClient(UnixSocketAddress(path));
}
@@ -84,33 +104,139 @@
return false;
}
- addClientConnection(std::move(serverFd));
- return true;
+ return addOutgoingConnection(std::move(serverFd), false);
}
sp<IBinder> RpcSession::getRootObject() {
- ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
- return state()->getRootObject(connection.fd(), sp<RpcSession>::fromExisting(this));
+ ExclusiveConnection connection;
+ status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ ConnectionUse::CLIENT, &connection);
+ if (status != OK) return nullptr;
+ return state()->getRootObject(connection.get(), sp<RpcSession>::fromExisting(this));
}
status_t RpcSession::getRemoteMaxThreads(size_t* maxThreads) {
- ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
- return state()->getMaxThreads(connection.fd(), sp<RpcSession>::fromExisting(this), maxThreads);
+ ExclusiveConnection connection;
+ status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ ConnectionUse::CLIENT, &connection);
+ if (status != OK) return status;
+ return state()->getMaxThreads(connection.get(), sp<RpcSession>::fromExisting(this), maxThreads);
}
-status_t RpcSession::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
+bool RpcSession::shutdownAndWait(bool wait) {
+ std::unique_lock<std::mutex> _l(mMutex);
+ LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr, "Shutdown trigger not installed");
+
+ mShutdownTrigger->trigger();
+
+ if (wait) {
+ LOG_ALWAYS_FATAL_IF(mShutdownListener == nullptr, "Shutdown listener not installed");
+ mShutdownListener->waitForShutdown(_l);
+ LOG_ALWAYS_FATAL_IF(!mThreads.empty(), "Shutdown failed");
+ }
+
+ _l.unlock();
+ mState->clear();
+
+ return true;
+}
+
+status_t RpcSession::transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
- ExclusiveConnection connection(sp<RpcSession>::fromExisting(this),
- (flags & IBinder::FLAG_ONEWAY) ? ConnectionUse::CLIENT_ASYNC
- : ConnectionUse::CLIENT);
- return state()->transact(connection.fd(), address, code, data,
+ ExclusiveConnection connection;
+ status_t status =
+ ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ (flags & IBinder::FLAG_ONEWAY) ? ConnectionUse::CLIENT_ASYNC
+ : ConnectionUse::CLIENT,
+ &connection);
+ if (status != OK) return status;
+ return state()->transact(connection.get(), binder, code, data,
sp<RpcSession>::fromExisting(this), reply, flags);
}
status_t RpcSession::sendDecStrong(const RpcAddress& address) {
- ExclusiveConnection connection(sp<RpcSession>::fromExisting(this),
- ConnectionUse::CLIENT_REFCOUNT);
- return state()->sendDecStrong(connection.fd(), address);
+ ExclusiveConnection connection;
+ status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ ConnectionUse::CLIENT_REFCOUNT, &connection);
+ if (status != OK) return status;
+ return state()->sendDecStrong(connection.get(), sp<RpcSession>::fromExisting(this), address);
+}
+
+std::unique_ptr<RpcSession::FdTrigger> RpcSession::FdTrigger::make() {
+ auto ret = std::make_unique<RpcSession::FdTrigger>();
+ if (!android::base::Pipe(&ret->mRead, &ret->mWrite)) {
+ ALOGE("Could not create pipe %s", strerror(errno));
+ return nullptr;
+ }
+ return ret;
+}
+
+void RpcSession::FdTrigger::trigger() {
+ mWrite.reset();
+}
+
+bool RpcSession::FdTrigger::isTriggered() {
+ return mWrite == -1;
+}
+
+status_t RpcSession::FdTrigger::triggerablePoll(base::borrowed_fd fd, int16_t event) {
+ while (true) {
+ pollfd pfd[]{{.fd = fd.get(), .events = static_cast<int16_t>(event), .revents = 0},
+ {.fd = mRead.get(), .events = POLLHUP, .revents = 0}};
+ int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1));
+ if (ret < 0) {
+ return -errno;
+ }
+ if (ret == 0) {
+ continue;
+ }
+ if (pfd[1].revents & POLLHUP) {
+ return -ECANCELED;
+ }
+ return pfd[0].revents & event ? OK : DEAD_OBJECT;
+ }
+}
+
+status_t RpcSession::FdTrigger::interruptableWriteFully(base::borrowed_fd fd, const void* data,
+ size_t size) {
+ const uint8_t* buffer = reinterpret_cast<const uint8_t*>(data);
+ const uint8_t* end = buffer + size;
+
+ MAYBE_WAIT_IN_FLAKE_MODE;
+
+ status_t status;
+ while ((status = triggerablePoll(fd, POLLOUT)) == OK) {
+ ssize_t writeSize = TEMP_FAILURE_RETRY(send(fd.get(), buffer, end - buffer, MSG_NOSIGNAL));
+ if (writeSize == 0) return DEAD_OBJECT;
+
+ if (writeSize < 0) {
+ return -errno;
+ }
+ buffer += writeSize;
+ if (buffer == end) return OK;
+ }
+ return status;
+}
+
+status_t RpcSession::FdTrigger::interruptableReadFully(base::borrowed_fd fd, void* data,
+ size_t size) {
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(data);
+ uint8_t* end = buffer + size;
+
+ MAYBE_WAIT_IN_FLAKE_MODE;
+
+ status_t status;
+ while ((status = triggerablePoll(fd, POLLIN)) == OK) {
+ ssize_t readSize = TEMP_FAILURE_RETRY(recv(fd.get(), buffer, end - buffer, MSG_NOSIGNAL));
+ if (readSize == 0) return DEAD_OBJECT; // EOF
+
+ if (readSize < 0) {
+ return -errno;
+ }
+ buffer += readSize;
+ if (buffer == end) return OK;
+ }
+ return status;
}
status_t RpcSession::readId() {
@@ -119,19 +245,39 @@
LOG_ALWAYS_FATAL_IF(mForServer != nullptr, "Can only update ID for client.");
}
- int32_t id;
-
- ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
- status_t status =
- state()->getSessionId(connection.fd(), sp<RpcSession>::fromExisting(this), &id);
+ ExclusiveConnection connection;
+ status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+ ConnectionUse::CLIENT, &connection);
if (status != OK) return status;
- LOG_RPC_DETAIL("RpcSession %p has id %d", this, id);
- mId = id;
+ mId = RpcAddress::zero();
+ status = state()->getSessionId(connection.get(), sp<RpcSession>::fromExisting(this),
+ &mId.value());
+ if (status != OK) return status;
+
+ LOG_RPC_DETAIL("RpcSession %p has id %s", this, mId->toString().c_str());
return OK;
}
-void RpcSession::preJoin(std::thread thread) {
+void RpcSession::WaitForShutdownListener::onSessionLockedAllIncomingThreadsEnded(
+ const sp<RpcSession>& session) {
+ (void)session;
+ mShutdown = true;
+}
+
+void RpcSession::WaitForShutdownListener::onSessionIncomingThreadEnded() {
+ mCv.notify_all();
+}
+
+void RpcSession::WaitForShutdownListener::waitForShutdown(std::unique_lock<std::mutex>& lock) {
+ while (!mShutdown) {
+ if (std::cv_status::timeout == mCv.wait_for(lock, std::chrono::seconds(1))) {
+ ALOGE("Waiting for RpcSession to shut down (1s w/o progress).");
+ }
+ }
+}
+
+void RpcSession::preJoinThreadOwnership(std::thread thread) {
LOG_ALWAYS_FATAL_IF(thread.get_id() != std::this_thread::get_id(), "Must own this thread");
{
@@ -140,64 +286,134 @@
}
}
-void RpcSession::join(unique_fd client) {
+RpcSession::PreJoinSetupResult RpcSession::preJoinSetup(base::unique_fd fd) {
// must be registered to allow arbitrary client code executing commands to
// be able to do nested calls (we can't only read from it)
- sp<RpcConnection> connection = assignServerToThisThread(std::move(client));
+ sp<RpcConnection> connection = assignIncomingConnectionToThisThread(std::move(fd));
- while (true) {
- status_t error =
- state()->getAndExecuteCommand(connection->fd, sp<RpcSession>::fromExisting(this));
+ status_t status = mState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
- if (error != OK) {
- ALOGI("Binder connection thread closing w/ status %s", statusToString(error).c_str());
- break;
+ return PreJoinSetupResult{
+ .connection = std::move(connection),
+ .status = status,
+ };
+}
+
+namespace {
+// RAII object for attaching / detaching current thread to JVM if Android Runtime exists. If
+// Android Runtime doesn't exist, no-op.
+class JavaThreadAttacher {
+public:
+ JavaThreadAttacher() {
+ // Use dlsym to find androidJavaAttachThread because libandroid_runtime is loaded after
+ // libbinder.
+ auto vm = getJavaVM();
+ if (vm == nullptr) return;
+
+ char threadName[16];
+ if (0 != pthread_getname_np(pthread_self(), threadName, sizeof(threadName))) {
+ constexpr const char* defaultThreadName = "UnknownRpcSessionThread";
+ memcpy(threadName, defaultThreadName,
+ std::min<size_t>(sizeof(threadName), strlen(defaultThreadName) + 1));
+ }
+ LOG_RPC_DETAIL("Attaching current thread %s to JVM", threadName);
+ JavaVMAttachArgs args;
+ args.version = JNI_VERSION_1_2;
+ args.name = threadName;
+ args.group = nullptr;
+ JNIEnv* env;
+
+ LOG_ALWAYS_FATAL_IF(vm->AttachCurrentThread(&env, &args) != JNI_OK,
+ "Cannot attach thread %s to JVM", threadName);
+ mAttached = true;
+ }
+ ~JavaThreadAttacher() {
+ if (!mAttached) return;
+ auto vm = getJavaVM();
+ LOG_ALWAYS_FATAL_IF(vm == nullptr,
+ "Unable to detach thread. No JavaVM, but it was present before!");
+
+ LOG_RPC_DETAIL("Detaching current thread from JVM");
+ if (vm->DetachCurrentThread() != JNI_OK) {
+ mAttached = false;
+ } else {
+ ALOGW("Unable to detach current thread from JVM");
}
}
- LOG_ALWAYS_FATAL_IF(!removeServerConnection(connection),
+private:
+ DISALLOW_COPY_AND_ASSIGN(JavaThreadAttacher);
+ bool mAttached = false;
+
+ static JavaVM* getJavaVM() {
+ static auto fn = reinterpret_cast<decltype(&AndroidRuntimeGetJavaVM)>(
+ dlsym(RTLD_DEFAULT, "AndroidRuntimeGetJavaVM"));
+ if (fn == nullptr) return nullptr;
+ return fn();
+ }
+};
+} // namespace
+
+void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult) {
+ sp<RpcConnection>& connection = setupResult.connection;
+
+ if (setupResult.status == OK) {
+ JavaThreadAttacher javaThreadAttacher;
+ while (true) {
+ status_t status = session->state()->getAndExecuteCommand(connection, session,
+ RpcState::CommandType::ANY);
+ if (status != OK) {
+ LOG_RPC_DETAIL("Binder connection thread closing w/ status %s",
+ statusToString(status).c_str());
+ break;
+ }
+ }
+ } else {
+ ALOGE("Connection failed to init, closing with status %s",
+ statusToString(setupResult.status).c_str());
+ }
+
+ LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection),
"bad state: connection object guaranteed to be in list");
+ sp<RpcSession::EventListener> listener;
{
- std::lock_guard<std::mutex> _l(mMutex);
- auto it = mThreads.find(std::this_thread::get_id());
- LOG_ALWAYS_FATAL_IF(it == mThreads.end());
+ std::lock_guard<std::mutex> _l(session->mMutex);
+ auto it = session->mThreads.find(std::this_thread::get_id());
+ LOG_ALWAYS_FATAL_IF(it == session->mThreads.end());
it->second.detach();
- mThreads.erase(it);
+ session->mThreads.erase(it);
+
+ listener = session->mEventListener.promote();
+ }
+
+ session = nullptr;
+
+ if (listener != nullptr) {
+ listener->onSessionIncomingThreadEnded();
}
}
-void RpcSession::terminateLocked() {
- // TODO(b/185167543):
- // - kindly notify other side of the connection of termination (can't be
- // locked)
- // - prevent new client/servers from being added
- // - stop all threads which are currently reading/writing
- // - terminate RpcState?
-
- if (mTerminated) return;
-
+sp<RpcServer> RpcSession::server() {
+ RpcServer* unsafeServer = mForServer.unsafe_get();
sp<RpcServer> server = mForServer.promote();
- if (server) {
- server->onSessionTerminating(sp<RpcSession>::fromExisting(this));
- }
-}
-wp<RpcServer> RpcSession::server() {
- return mForServer;
+ LOG_ALWAYS_FATAL_IF((unsafeServer == nullptr) != (server == nullptr),
+ "wp<> is to avoid strong cycle only");
+ return server;
}
bool RpcSession::setupSocketClient(const RpcSocketAddress& addr) {
{
std::lock_guard<std::mutex> _l(mMutex);
- LOG_ALWAYS_FATAL_IF(mClientConnections.size() != 0,
+ LOG_ALWAYS_FATAL_IF(mOutgoingConnections.size() != 0,
"Must only setup session once, but already has %zu clients",
- mClientConnections.size());
+ mOutgoingConnections.size());
}
- if (!setupOneSocketClient(addr, RPC_SESSION_ID_NEW)) return false;
+ if (!setupOneSocketConnection(addr, RpcAddress::zero(), false /*incoming*/)) return false;
- // TODO(b/185167543): we should add additional sessions dynamically
+ // TODO(b/189955605): we should add additional sessions dynamically
// instead of all at once.
// TODO(b/186470974): first risk of blocking
size_t numThreadsAvailable;
@@ -215,14 +431,25 @@
// we've already setup one client
for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
- // TODO(b/185167543): shutdown existing connections?
- if (!setupOneSocketClient(addr, mId.value())) return false;
+ // TODO(b/189955605): shutdown existing connections?
+ if (!setupOneSocketConnection(addr, mId.value(), false /*incoming*/)) return false;
+ }
+
+ // TODO(b/189955605): we should add additional sessions dynamically
+ // instead of all at once - the other side should be responsible for setting
+ // up additional connections. We need to create at least one (unless 0 are
+ // requested to be set) in order to allow the other side to reliably make
+ // any requests at all.
+
+ for (size_t i = 0; i < mMaxThreads; i++) {
+ if (!setupOneSocketConnection(addr, mId.value(), true /*incoming*/)) return false;
}
return true;
}
-bool RpcSession::setupOneSocketClient(const RpcSocketAddress& addr, int32_t id) {
+bool RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, const RpcAddress& id,
+ bool incoming) {
for (size_t tries = 0; tries < 5; tries++) {
if (tries > 0) usleep(10000);
@@ -246,77 +473,157 @@
return false;
}
- if (sizeof(id) != TEMP_FAILURE_RETRY(write(serverFd.get(), &id, sizeof(id)))) {
+ RpcConnectionHeader header{.options = 0};
+ memcpy(&header.sessionId, &id.viewRawEmbedded(), sizeof(RpcWireAddress));
+
+ if (incoming) header.options |= RPC_CONNECTION_OPTION_INCOMING;
+
+ if (sizeof(header) != TEMP_FAILURE_RETRY(write(serverFd.get(), &header, sizeof(header)))) {
int savedErrno = errno;
- ALOGE("Could not write id to socket at %s: %s", addr.toString().c_str(),
+ ALOGE("Could not write connection header to 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());
- addClientConnection(std::move(serverFd));
- return true;
+ if (incoming) {
+ return addIncomingConnection(std::move(serverFd));
+ } else {
+ return addOutgoingConnection(std::move(serverFd), true);
+ }
}
ALOGE("Ran out of retries to connect to %s", addr.toString().c_str());
return false;
}
-void RpcSession::addClientConnection(unique_fd fd) {
- std::lock_guard<std::mutex> _l(mMutex);
- sp<RpcConnection> session = sp<RpcConnection>::make();
- session->fd = std::move(fd);
- mClientConnections.push_back(session);
+bool RpcSession::addIncomingConnection(unique_fd fd) {
+ std::mutex mutex;
+ std::condition_variable joinCv;
+ std::unique_lock<std::mutex> lock(mutex);
+ std::thread thread;
+ sp<RpcSession> thiz = sp<RpcSession>::fromExisting(this);
+ bool ownershipTransferred = false;
+ thread = std::thread([&]() {
+ std::unique_lock<std::mutex> threadLock(mutex);
+ unique_fd movedFd = std::move(fd);
+ // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
+ sp<RpcSession> session = thiz;
+ session->preJoinThreadOwnership(std::move(thread));
+
+ // only continue once we have a response or the connection fails
+ auto setupResult = session->preJoinSetup(std::move(movedFd));
+
+ ownershipTransferred = true;
+ threadLock.unlock();
+ joinCv.notify_one();
+ // do not use & vars below
+
+ RpcSession::join(std::move(session), std::move(setupResult));
+ });
+ joinCv.wait(lock, [&] { return ownershipTransferred; });
+ LOG_ALWAYS_FATAL_IF(!ownershipTransferred);
+ return true;
}
-void RpcSession::setForServer(const wp<RpcServer>& server, int32_t sessionId) {
+bool RpcSession::addOutgoingConnection(unique_fd fd, bool init) {
+ sp<RpcConnection> connection = sp<RpcConnection>::make();
+ {
+ std::lock_guard<std::mutex> _l(mMutex);
+
+ // first client connection added, but setForServer not called, so
+ // initializaing for a client.
+ if (mShutdownTrigger == nullptr) {
+ mShutdownTrigger = FdTrigger::make();
+ mEventListener = mShutdownListener = sp<WaitForShutdownListener>::make();
+ if (mShutdownTrigger == nullptr) return false;
+ }
+
+ connection->fd = std::move(fd);
+ connection->exclusiveTid = gettid();
+ mOutgoingConnections.push_back(connection);
+ }
+
+ status_t status = OK;
+ if (init) {
+ mState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+ }
+
+ {
+ std::lock_guard<std::mutex> _l(mMutex);
+ connection->exclusiveTid = std::nullopt;
+ }
+
+ return status == OK;
+}
+
+bool RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListener>& eventListener,
+ const RpcAddress& sessionId) {
+ LOG_ALWAYS_FATAL_IF(mForServer != nullptr);
+ LOG_ALWAYS_FATAL_IF(server == nullptr);
+ LOG_ALWAYS_FATAL_IF(mEventListener != nullptr);
+ LOG_ALWAYS_FATAL_IF(eventListener == nullptr);
+ LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr);
+
+ mShutdownTrigger = FdTrigger::make();
+ if (mShutdownTrigger == nullptr) return false;
+
mId = sessionId;
mForServer = server;
+ mEventListener = eventListener;
+ return true;
}
-sp<RpcSession::RpcConnection> RpcSession::assignServerToThisThread(unique_fd fd) {
+sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(unique_fd fd) {
std::lock_guard<std::mutex> _l(mMutex);
sp<RpcConnection> session = sp<RpcConnection>::make();
session->fd = std::move(fd);
session->exclusiveTid = gettid();
- mServerConnections.push_back(session);
+ mIncomingConnections.push_back(session);
return session;
}
-bool RpcSession::removeServerConnection(const sp<RpcConnection>& connection) {
+bool RpcSession::removeIncomingConnection(const sp<RpcConnection>& connection) {
std::lock_guard<std::mutex> _l(mMutex);
- if (auto it = std::find(mServerConnections.begin(), mServerConnections.end(), connection);
- it != mServerConnections.end()) {
- mServerConnections.erase(it);
- if (mServerConnections.size() == 0) {
- terminateLocked();
+ if (auto it = std::find(mIncomingConnections.begin(), mIncomingConnections.end(), connection);
+ it != mIncomingConnections.end()) {
+ mIncomingConnections.erase(it);
+ if (mIncomingConnections.size() == 0) {
+ sp<EventListener> listener = mEventListener.promote();
+ if (listener) {
+ listener->onSessionLockedAllIncomingThreadsEnded(
+ sp<RpcSession>::fromExisting(this));
+ }
}
return true;
}
return false;
}
-RpcSession::ExclusiveConnection::ExclusiveConnection(const sp<RpcSession>& session,
- ConnectionUse use)
- : mSession(session) {
- pid_t tid = gettid();
- std::unique_lock<std::mutex> _l(mSession->mMutex);
+status_t RpcSession::ExclusiveConnection::find(const sp<RpcSession>& session, ConnectionUse use,
+ ExclusiveConnection* connection) {
+ connection->mSession = session;
+ connection->mConnection = nullptr;
+ connection->mReentrant = false;
- mSession->mWaitingThreads++;
+ pid_t tid = gettid();
+ std::unique_lock<std::mutex> _l(session->mMutex);
+
+ session->mWaitingThreads++;
while (true) {
sp<RpcConnection> exclusive;
sp<RpcConnection> available;
// CHECK FOR DEDICATED CLIENT SOCKET
//
- // A server/looper should always use a dedicated session if available
- findConnection(tid, &exclusive, &available, mSession->mClientConnections,
- mSession->mClientConnectionsOffset);
+ // A server/looper should always use a dedicated connection if available
+ findConnection(tid, &exclusive, &available, session->mOutgoingConnections,
+ session->mOutgoingConnectionsOffset);
// WARNING: this assumes a server cannot request its client to send
- // a transaction, as mServerConnections is excluded below.
+ // a transaction, as mIncomingConnections is excluded below.
//
// Imagine we have more than one thread in play, and a single thread
// sends a synchronous, then an asynchronous command. Imagine the
@@ -326,41 +633,59 @@
// command. So, we move to considering the second available thread
// for subsequent calls.
if (use == ConnectionUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
- mSession->mClientConnectionsOffset =
- (mSession->mClientConnectionsOffset + 1) % mSession->mClientConnections.size();
+ session->mOutgoingConnectionsOffset = (session->mOutgoingConnectionsOffset + 1) %
+ session->mOutgoingConnections.size();
}
- // USE SERVING SOCKET (for nested transaction)
- //
- // asynchronous calls cannot be nested
+ // USE SERVING SOCKET (e.g. nested transaction)
if (use != ConnectionUse::CLIENT_ASYNC) {
+ sp<RpcConnection> exclusiveIncoming;
// server connections are always assigned to a thread
- findConnection(tid, &exclusive, nullptr /*available*/, mSession->mServerConnections,
- 0 /* index hint */);
+ findConnection(tid, &exclusiveIncoming, nullptr /*available*/,
+ session->mIncomingConnections, 0 /* index hint */);
+
+ // asynchronous calls cannot be nested, we currently allow ref count
+ // calls to be nested (so that you can use this without having extra
+ // threads). Note 'drainCommands' is used so that these ref counts can't
+ // build up.
+ if (exclusiveIncoming != nullptr) {
+ if (exclusiveIncoming->allowNested) {
+ // guaranteed to be processed as nested command
+ exclusive = exclusiveIncoming;
+ } else if (use == ConnectionUse::CLIENT_REFCOUNT && available == nullptr) {
+ // prefer available socket, but if we don't have one, don't
+ // wait for one
+ exclusive = exclusiveIncoming;
+ }
+ }
}
- // if our thread is already using a session, prioritize using that
+ // if our thread is already using a connection, prioritize using that
if (exclusive != nullptr) {
- mConnection = exclusive;
- mReentrant = true;
+ connection->mConnection = exclusive;
+ connection->mReentrant = true;
break;
} else if (available != nullptr) {
- mConnection = available;
- mConnection->exclusiveTid = tid;
+ connection->mConnection = available;
+ connection->mConnection->exclusiveTid = tid;
break;
}
- // in regular binder, this would usually be a deadlock :)
- LOG_ALWAYS_FATAL_IF(mSession->mClientConnections.size() == 0,
- "Not a client of any session. You must create a session to an "
- "RPC server to make any non-nested (e.g. oneway or on another thread) "
- "calls.");
+ if (session->mOutgoingConnections.size() == 0) {
+ ALOGE("Session has no client connections. This is required for an RPC server to make "
+ "any non-nested (e.g. oneway or on another thread) calls. Use: %d. Server "
+ "connections: %zu",
+ static_cast<int>(use), session->mIncomingConnections.size());
+ return WOULD_BLOCK;
+ }
- LOG_RPC_DETAIL("No available session (have %zu clients and %zu servers). Waiting...",
- mSession->mClientConnections.size(), mSession->mServerConnections.size());
- mSession->mAvailableConnectionCv.wait(_l);
+ LOG_RPC_DETAIL("No available connections (have %zu clients and %zu servers). Waiting...",
+ session->mOutgoingConnections.size(), session->mIncomingConnections.size());
+ session->mAvailableConnectionCv.wait(_l);
}
- mSession->mWaitingThreads--;
+ session->mWaitingThreads--;
+
+ return OK;
}
void RpcSession::ExclusiveConnection::findConnection(pid_t tid, sp<RpcConnection>* exclusive,
@@ -375,13 +700,13 @@
for (size_t i = 0; i < sockets.size(); i++) {
sp<RpcConnection>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
- // take first available session (intuition = caching)
+ // take first available connection (intuition = caching)
if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
*available = socket;
continue;
}
- // though, prefer to take session which is already inuse by this thread
+ // though, prefer to take connection which is already inuse by this thread
// (nested transactions)
if (exclusive && socket->exclusiveTid == tid) {
*exclusive = socket;
@@ -391,10 +716,10 @@
}
RpcSession::ExclusiveConnection::~ExclusiveConnection() {
- // reentrant use of a session means something less deep in the call stack
+ // reentrant use of a connection means something less deep in the call stack
// is using this fd, and it retains the right to it. So, we don't give up
// exclusive ownership, and no thread is freed.
- if (!mReentrant) {
+ if (!mReentrant && mConnection != nullptr) {
std::unique_lock<std::mutex> _l(mSession->mMutex);
mConnection->exclusiveTid = std::nullopt;
if (mSession->mWaitingThreads > 0) {
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 2ba9fa2..332c75f 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -18,16 +18,35 @@
#include "RpcState.h"
+#include <android-base/scopeguard.h>
#include <binder/BpBinder.h>
+#include <binder/IPCThreadState.h>
#include <binder/RpcServer.h>
#include "Debug.h"
#include "RpcWireFormat.h"
+#include <random>
+
#include <inttypes.h>
namespace android {
+using base::ScopeGuard;
+
+#if RPC_FLAKE_PRONE
+void rpcMaybeWaitToFlake() {
+ [[clang::no_destroy]] static std::random_device r;
+ [[clang::no_destroy]] static std::mutex m;
+ unsigned num;
+ {
+ std::lock_guard<std::mutex> lock(m);
+ num = r();
+ }
+ if (num % 10 == 0) usleep(num % 1000);
+}
+#endif
+
RpcState::RpcState() {}
RpcState::~RpcState() {}
@@ -57,6 +76,7 @@
}
std::lock_guard<std::mutex> _l(mNodeMutex);
+ if (mTerminated) return DEAD_OBJECT;
// TODO(b/182939933): maybe move address out of BpBinder, and keep binder->address map
// in RpcState
@@ -78,24 +98,50 @@
}
LOG_ALWAYS_FATAL_IF(isRpc, "RPC binder must have known address at this point");
- auto&& [it, inserted] = mNodeForAddress.insert({RpcAddress::unique(),
- BinderNode{
- .binder = binder,
- .timesSent = 1,
- .sentRef = binder,
- }});
- // TODO(b/182939933): better organization could avoid needing this log
- LOG_ALWAYS_FATAL_IF(!inserted);
+ bool forServer = session->server() != nullptr;
- *outAddress = it->first;
- return OK;
+ for (size_t tries = 0; tries < 5; tries++) {
+ auto&& [it, inserted] = mNodeForAddress.insert({RpcAddress::random(forServer),
+ BinderNode{
+ .binder = binder,
+ .timesSent = 1,
+ .sentRef = binder,
+ }});
+ if (inserted) {
+ *outAddress = it->first;
+ return OK;
+ }
+
+ // well, we don't have visibility into the header here, but still
+ static_assert(sizeof(RpcWireAddress) == 40, "this log needs updating");
+ ALOGW("2**256 is 1e77. If you see this log, you probably have some entropy issue, or maybe "
+ "you witness something incredible!");
+ }
+
+ ALOGE("Unable to create an address in order to send out %p", binder.get());
+ return WOULD_BLOCK;
}
-sp<IBinder> RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address) {
+status_t RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address,
+ sp<IBinder>* out) {
+ // ensure that: if we want to use addresses for something else in the future (for
+ // instance, allowing transitive binder sends), that we don't accidentally
+ // send those addresses to old server. Accidentally ignoring this in that
+ // case and considering the binder to be recognized could cause this
+ // process to accidentally proxy transactions for that binder. Of course,
+ // if we communicate with a binder, it could always be proxying
+ // information. However, we want to make sure that isn't done on accident
+ // by a client.
+ if (!address.isRecognizedType()) {
+ ALOGE("Address is of an unknown type, rejecting: %s", address.toString().c_str());
+ return BAD_VALUE;
+ }
+
std::unique_lock<std::mutex> _l(mNodeMutex);
+ if (mTerminated) return DEAD_OBJECT;
if (auto it = mNodeForAddress.find(address); it != mNodeForAddress.end()) {
- sp<IBinder> binder = it->second.binder.promote();
+ *out = it->second.binder.promote();
// implicitly have strong RPC refcount, since we received this binder
it->second.timesRecd++;
@@ -107,7 +153,15 @@
// immediately, we wait to send the last one in BpBinder::onLastDecStrong.
(void)session->sendDecStrong(address);
- return binder;
+ return OK;
+ }
+
+ // we don't know about this binder, so the other side of the connection
+ // should have created it.
+ if (address.isForServer() == !!session->server()) {
+ ALOGE("Server received unrecognized address which we should own the creation of %s.",
+ address.toString().c_str());
+ return BAD_VALUE;
}
auto&& [it, inserted] = mNodeForAddress.insert({address, BinderNode{}});
@@ -115,10 +169,9 @@
// Currently, all binders are assumed to be part of the same session (no
// device global binders in the RPC world).
- sp<IBinder> binder = BpBinder::create(session, it->first);
- it->second.binder = binder;
+ it->second.binder = *out = BpBinder::create(session, it->first);
it->second.timesRecd = 1;
- return binder;
+ return OK;
}
size_t RpcState::countBinders() {
@@ -128,6 +181,45 @@
void RpcState::dump() {
std::lock_guard<std::mutex> _l(mNodeMutex);
+ dumpLocked();
+}
+
+void RpcState::clear() {
+ std::unique_lock<std::mutex> _l(mNodeMutex);
+
+ if (mTerminated) {
+ LOG_ALWAYS_FATAL_IF(!mNodeForAddress.empty(),
+ "New state should be impossible after terminating!");
+ return;
+ }
+
+ if (SHOULD_LOG_RPC_DETAIL) {
+ ALOGE("RpcState::clear()");
+ dumpLocked();
+ }
+
+ // if the destructor of a binder object makes another RPC call, then calling
+ // decStrong could deadlock. So, we must hold onto these binders until
+ // mNodeMutex is no longer taken.
+ std::vector<sp<IBinder>> tempHoldBinder;
+
+ mTerminated = true;
+ for (auto& [address, node] : mNodeForAddress) {
+ sp<IBinder> binder = node.binder.promote();
+ LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
+
+ if (node.sentRef != nullptr) {
+ tempHoldBinder.push_back(node.sentRef);
+ }
+ }
+
+ mNodeForAddress.clear();
+
+ _l.unlock();
+ tempHoldBinder.clear(); // explicit
+}
+
+void RpcState::dumpLocked() {
ALOGE("DUMP OF RpcState %p", this);
ALOGE("DUMP OF RpcState (%zu nodes)", mNodeForAddress.size());
for (const auto& [address, node] : mNodeForAddress) {
@@ -155,32 +247,6 @@
ALOGE("END DUMP OF RpcState");
}
-void RpcState::terminate() {
- if (SHOULD_LOG_RPC_DETAIL) {
- ALOGE("RpcState::terminate()");
- dump();
- }
-
- // if the destructor of a binder object makes another RPC call, then calling
- // decStrong could deadlock. So, we must hold onto these binders until
- // mNodeMutex is no longer taken.
- std::vector<sp<IBinder>> tempHoldBinder;
-
- {
- std::lock_guard<std::mutex> _l(mNodeMutex);
- mTerminated = true;
- for (auto& [address, node] : mNodeForAddress) {
- sp<IBinder> binder = node.binder.promote();
- LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
-
- if (node.sentRef != nullptr) {
- tempHoldBinder.push_back(node.sentRef);
- }
- }
-
- mNodeForAddress.clear();
- }
-}
RpcState::CommandData::CommandData(size_t size) : mSize(size) {
// The maximum size for regular binder is 1MB for all concurrent
@@ -203,62 +269,84 @@
mData.reset(new (std::nothrow) uint8_t[size]);
}
-bool RpcState::rpcSend(const base::unique_fd& fd, const char* what, const void* data, size_t size) {
- LOG_RPC_DETAIL("Sending %s on fd %d: %s", what, fd.get(), hexString(data, size).c_str());
+status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const char* what, const void* data,
+ size_t size) {
+ LOG_RPC_DETAIL("Sending %s on fd %d: %s", what, connection->fd.get(),
+ hexString(data, size).c_str());
if (size > std::numeric_limits<ssize_t>::max()) {
ALOGE("Cannot send %s at size %zu (too big)", what, size);
- terminate();
- return false;
+ (void)session->shutdownAndWait(false);
+ return BAD_VALUE;
}
- 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,
- fd.get(), strerror(errno));
-
- terminate();
- return false;
+ if (status_t status = session->mShutdownTrigger->interruptableWriteFully(connection->fd.get(),
+ data, size);
+ status != OK) {
+ LOG_RPC_DETAIL("Failed to write %s (%zu bytes) on fd %d, error: %s", what, size,
+ connection->fd.get(), statusToString(status).c_str());
+ (void)session->shutdownAndWait(false);
+ return status;
}
- return true;
+ return OK;
}
-bool RpcState::rpcRec(const base::unique_fd& fd, const char* what, void* data, size_t size) {
+status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const char* what, void* data,
+ size_t size) {
if (size > std::numeric_limits<ssize_t>::max()) {
ALOGE("Cannot rec %s at size %zu (too big)", what, size);
- terminate();
- return false;
+ (void)session->shutdownAndWait(false);
+ return BAD_VALUE;
}
- 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();
-
- if (recd == 0 && errno == 0) {
- LOG_RPC_DETAIL("No more data when trying to read %s on fd %d", what, fd.get());
- return false;
- }
-
- ALOGE("Failed to read %s (received %zd of %zu bytes) on fd %d, error: %s", what, recd, size,
- fd.get(), strerror(errno));
- return false;
- } else {
- LOG_RPC_DETAIL("Received %s on fd %d: %s", what, fd.get(), hexString(data, size).c_str());
+ if (status_t status =
+ session->mShutdownTrigger->interruptableReadFully(connection->fd.get(), data, size);
+ status != OK) {
+ LOG_RPC_DETAIL("Failed to read %s (%zu bytes) on fd %d, error: %s", what, size,
+ connection->fd.get(), statusToString(status).c_str());
+ return status;
}
- return true;
+ LOG_RPC_DETAIL("Received %s on fd %d: %s", what, connection->fd.get(),
+ hexString(data, size).c_str());
+ return OK;
}
-sp<IBinder> RpcState::getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session) {
+status_t RpcState::sendConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session) {
+ RpcOutgoingConnectionInit init{
+ .msg = RPC_CONNECTION_INIT_OKAY,
+ };
+ return rpcSend(connection, session, "connection init", &init, sizeof(init));
+}
+
+status_t RpcState::readConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session) {
+ RpcOutgoingConnectionInit init;
+ if (status_t status = rpcRec(connection, session, "connection init", &init, sizeof(init));
+ status != OK)
+ return status;
+
+ static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY));
+ if (0 != strncmp(init.msg, RPC_CONNECTION_INIT_OKAY, sizeof(init.msg))) {
+ ALOGE("Connection init message unrecognized %.*s", static_cast<int>(sizeof(init.msg)),
+ init.msg);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+sp<IBinder> RpcState::getRootObject(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session) {
Parcel data;
data.markForRpc(session);
Parcel reply;
- status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_ROOT, data, session,
- &reply, 0);
+ status_t status = transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_ROOT,
+ data, session, &reply, 0);
if (status != OK) {
ALOGE("Error getting root object: %s", statusToString(status).c_str());
return nullptr;
@@ -267,14 +355,15 @@
return reply.readStrongBinder();
}
-status_t RpcState::getMaxThreads(const base::unique_fd& fd, const sp<RpcSession>& session,
- size_t* maxThreadsOut) {
+status_t RpcState::getMaxThreads(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, size_t* maxThreadsOut) {
Parcel data;
data.markForRpc(session);
Parcel reply;
- status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_MAX_THREADS, data,
- session, &reply, 0);
+ status_t status =
+ transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_MAX_THREADS,
+ data, session, &reply, 0);
if (status != OK) {
ALOGE("Error getting max threads: %s", statusToString(status).c_str());
return status;
@@ -292,44 +381,26 @@
return OK;
}
-status_t RpcState::getSessionId(const base::unique_fd& fd, const sp<RpcSession>& session,
- int32_t* sessionIdOut) {
+status_t RpcState::getSessionId(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, RpcAddress* sessionIdOut) {
Parcel data;
data.markForRpc(session);
Parcel reply;
- status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_SESSION_ID, data,
- session, &reply, 0);
+ status_t status =
+ transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_SESSION_ID,
+ data, session, &reply, 0);
if (status != OK) {
ALOGE("Error getting session ID: %s", statusToString(status).c_str());
return status;
}
- int32_t sessionId;
- status = reply.readInt32(&sessionId);
- if (status != OK) return status;
-
- *sessionIdOut = sessionId;
- return OK;
+ return sessionIdOut->readFromParcel(reply);
}
-status_t RpcState::transact(const base::unique_fd& fd, const RpcAddress& address, uint32_t code,
- const Parcel& data, const sp<RpcSession>& session, Parcel* reply,
- uint32_t flags) {
- uint64_t asyncNumber = 0;
-
- if (!address.isZero()) {
- std::lock_guard<std::mutex> _l(mNodeMutex);
- if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
- auto it = mNodeForAddress.find(address);
- LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s",
- address.toString().c_str());
-
- if (flags & IBinder::FLAG_ONEWAY) {
- asyncNumber = it->second.asyncNumber++;
- }
- }
-
+status_t RpcState::transact(const sp<RpcSession::RpcConnection>& connection,
+ const sp<IBinder>& binder, uint32_t code, const Parcel& data,
+ const sp<RpcSession>& session, Parcel* reply, uint32_t flags) {
if (!data.isForRpc()) {
ALOGE("Refusing to send RPC with parcel not crafted for RPC");
return BAD_TYPE;
@@ -340,45 +411,83 @@
return BAD_TYPE;
}
+ RpcAddress address = RpcAddress::zero();
+ if (status_t status = onBinderLeaving(session, binder, &address); status != OK) return status;
+
+ return transactAddress(connection, address, code, data, session, reply, flags);
+}
+
+status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connection,
+ const RpcAddress& address, uint32_t code, const Parcel& data,
+ const sp<RpcSession>& session, Parcel* reply, uint32_t flags) {
+ LOG_ALWAYS_FATAL_IF(!data.isForRpc());
+ LOG_ALWAYS_FATAL_IF(data.objectsCount() != 0);
+
+ uint64_t asyncNumber = 0;
+
+ if (!address.isZero()) {
+ std::unique_lock<std::mutex> _l(mNodeMutex);
+ if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
+ auto it = mNodeForAddress.find(address);
+ LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s",
+ address.toString().c_str());
+
+ if (flags & IBinder::FLAG_ONEWAY) {
+ asyncNumber = it->second.asyncNumber;
+ if (!nodeProgressAsyncNumber(&it->second)) {
+ _l.unlock();
+ (void)session->shutdownAndWait(false);
+ return DEAD_OBJECT;
+ }
+ }
+ }
+
+ LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+ sizeof(RpcWireTransaction) <
+ data.dataSize(),
+ "Too much data %zu", data.dataSize());
+
+ RpcWireHeader command{
+ .command = RPC_COMMAND_TRANSACT,
+ .bodySize = static_cast<uint32_t>(sizeof(RpcWireTransaction) + data.dataSize()),
+ };
RpcWireTransaction transaction{
.address = address.viewRawEmbedded(),
.code = code,
.flags = flags,
.asyncNumber = asyncNumber,
};
-
- CommandData transactionData(sizeof(RpcWireTransaction) + data.dataSize());
+ CommandData transactionData(sizeof(RpcWireHeader) + sizeof(RpcWireTransaction) +
+ data.dataSize());
if (!transactionData.valid()) {
return NO_MEMORY;
}
- memcpy(transactionData.data() + 0, &transaction, sizeof(RpcWireTransaction));
- memcpy(transactionData.data() + sizeof(RpcWireTransaction), data.data(), data.dataSize());
+ memcpy(transactionData.data() + 0, &command, sizeof(RpcWireHeader));
+ memcpy(transactionData.data() + sizeof(RpcWireHeader), &transaction,
+ sizeof(RpcWireTransaction));
+ memcpy(transactionData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireTransaction), data.data(),
+ data.dataSize());
- if (transactionData.size() > std::numeric_limits<uint32_t>::max()) {
- ALOGE("Transaction size too big %zu", transactionData.size());
- return BAD_VALUE;
- }
-
- RpcWireHeader command{
- .command = RPC_COMMAND_TRANSACT,
- .bodySize = static_cast<uint32_t>(transactionData.size()),
- };
-
- if (!rpcSend(fd, "transact header", &command, sizeof(command))) {
- return DEAD_OBJECT;
- }
- if (!rpcSend(fd, "command body", transactionData.data(), transactionData.size())) {
- return DEAD_OBJECT;
- }
+ if (status_t status = rpcSend(connection, session, "transaction", transactionData.data(),
+ transactionData.size());
+ status != OK)
+ // TODO(b/167966510): need to undo onBinderLeaving - we know the
+ // refcount isn't successfully transferred.
+ return status;
if (flags & IBinder::FLAG_ONEWAY) {
- return OK; // do not wait for result
+ LOG_RPC_DETAIL("Oneway command, so no longer waiting on %d", connection->fd.get());
+
+ // Do not wait on result.
+ // However, too many oneway calls may cause refcounts to build up and fill up the socket,
+ // so process those.
+ return drainCommands(connection, session, CommandType::CONTROL_ONLY);
}
LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction.");
- return waitForReply(fd, session, reply);
+ return waitForReply(connection, session, reply);
}
static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,
@@ -387,36 +496,36 @@
delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data));
(void)dataSize;
LOG_ALWAYS_FATAL_IF(objects != nullptr);
- LOG_ALWAYS_FATAL_IF(objectsCount, 0);
+ LOG_ALWAYS_FATAL_IF(objectsCount != 0, "%zu objects remaining", objectsCount);
}
-status_t RpcState::waitForReply(const base::unique_fd& fd, const sp<RpcSession>& session,
- Parcel* reply) {
+status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, Parcel* reply) {
RpcWireHeader command;
while (true) {
- if (!rpcRec(fd, "command header", &command, sizeof(command))) {
- return DEAD_OBJECT;
- }
+ if (status_t status =
+ rpcRec(connection, session, "command header", &command, sizeof(command));
+ status != OK)
+ return status;
if (command.command == RPC_COMMAND_REPLY) break;
- status_t status = processServerCommand(fd, session, command);
- if (status != OK) return status;
+ if (status_t status = processCommand(connection, session, command, CommandType::ANY);
+ status != OK)
+ return status;
}
CommandData data(command.bodySize);
- if (!data.valid()) {
- return NO_MEMORY;
- }
+ if (!data.valid()) return NO_MEMORY;
- if (!rpcRec(fd, "reply body", data.data(), command.bodySize)) {
- return DEAD_OBJECT;
- }
+ if (status_t status = rpcRec(connection, session, "reply body", data.data(), command.bodySize);
+ status != OK)
+ return status;
if (command.bodySize < sizeof(RpcWireReply)) {
ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireReply. Terminating!",
sizeof(RpcWireReply), command.bodySize);
- terminate();
+ (void)session->shutdownAndWait(false);
return BAD_VALUE;
}
RpcWireReply* rpcReply = reinterpret_cast<RpcWireReply*>(data.data());
@@ -431,7 +540,8 @@
return OK;
}
-status_t RpcState::sendDecStrong(const base::unique_fd& fd, const RpcAddress& addr) {
+status_t RpcState::sendDecStrong(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const RpcAddress& addr) {
{
std::lock_guard<std::mutex> _l(mNodeMutex);
if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
@@ -442,39 +552,71 @@
addr.toString().c_str());
it->second.timesRecd--;
- if (it->second.timesRecd == 0 && it->second.timesSent == 0) {
- mNodeForAddress.erase(it);
- }
+ LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
+ "Bad state. RpcState shouldn't own received binder");
}
RpcWireHeader cmd = {
.command = RPC_COMMAND_DEC_STRONG,
.bodySize = sizeof(RpcWireAddress),
};
- if (!rpcSend(fd, "dec ref header", &cmd, sizeof(cmd))) return DEAD_OBJECT;
- if (!rpcSend(fd, "dec ref body", &addr.viewRawEmbedded(), sizeof(RpcWireAddress)))
- return DEAD_OBJECT;
+ if (status_t status = rpcSend(connection, session, "dec ref header", &cmd, sizeof(cmd));
+ status != OK)
+ return status;
+ if (status_t status = rpcSend(connection, session, "dec ref body", &addr.viewRawEmbedded(),
+ sizeof(RpcWireAddress));
+ status != OK)
+ return status;
return OK;
}
-status_t RpcState::getAndExecuteCommand(const base::unique_fd& fd, const sp<RpcSession>& session) {
- LOG_RPC_DETAIL("getAndExecuteCommand on fd %d", fd.get());
+status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, CommandType type) {
+ LOG_RPC_DETAIL("getAndExecuteCommand on fd %d", connection->fd.get());
RpcWireHeader command;
- if (!rpcRec(fd, "command header", &command, sizeof(command))) {
- return DEAD_OBJECT;
- }
+ if (status_t status = rpcRec(connection, session, "command header", &command, sizeof(command));
+ status != OK)
+ return status;
- return processServerCommand(fd, session, command);
+ return processCommand(connection, session, command, type);
}
-status_t RpcState::processServerCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
- const RpcWireHeader& command) {
+status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, CommandType type) {
+ uint8_t buf;
+ while (0 < TEMP_FAILURE_RETRY(
+ recv(connection->fd.get(), &buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT))) {
+ status_t status = getAndExecuteCommand(connection, session, type);
+ if (status != OK) return status;
+ }
+ return OK;
+}
+
+status_t RpcState::processCommand(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const RpcWireHeader& command,
+ CommandType type) {
+ IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
+ IPCThreadState::SpGuard spGuard{
+ .address = __builtin_frame_address(0),
+ .context = "processing binder RPC command",
+ };
+ const IPCThreadState::SpGuard* origGuard;
+ if (kernelBinderState != nullptr) {
+ origGuard = kernelBinderState->pushGetCallingSpGuard(&spGuard);
+ }
+ ScopeGuard guardUnguard = [&]() {
+ if (kernelBinderState != nullptr) {
+ kernelBinderState->restoreGetCallingSpGuard(origGuard);
+ }
+ };
+
switch (command.command) {
case RPC_COMMAND_TRANSACT:
- return processTransact(fd, session, command);
+ if (type != CommandType::ANY) return BAD_TYPE;
+ return processTransact(connection, session, command);
case RPC_COMMAND_DEC_STRONG:
- return processDecStrong(fd, command);
+ return processDecStrong(connection, session, command);
}
// We should always know the version of the opposing side, and since the
@@ -483,22 +625,23 @@
// also can't consider it a fatal error because this would allow any client
// to kill us, so ending the session for misbehaving client.
ALOGE("Unknown RPC command %d - terminating session", command.command);
- terminate();
+ (void)session->shutdownAndWait(false);
return DEAD_OBJECT;
}
-status_t RpcState::processTransact(const base::unique_fd& fd, const sp<RpcSession>& session,
- const RpcWireHeader& command) {
+status_t RpcState::processTransact(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const RpcWireHeader& command) {
LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_TRANSACT, "command: %d", command.command);
CommandData transactionData(command.bodySize);
if (!transactionData.valid()) {
return NO_MEMORY;
}
- if (!rpcRec(fd, "transaction body", transactionData.data(), transactionData.size())) {
- return DEAD_OBJECT;
- }
+ if (status_t status = rpcRec(connection, session, "transaction body", transactionData.data(),
+ transactionData.size());
+ status != OK)
+ return status;
- return processTransactInternal(fd, session, std::move(transactionData));
+ return processTransactInternal(connection, session, std::move(transactionData));
}
static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
@@ -510,12 +653,19 @@
(void)objectsCount;
}
-status_t RpcState::processTransactInternal(const base::unique_fd& fd, const sp<RpcSession>& session,
+status_t RpcState::processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session,
CommandData transactionData) {
+ // for 'recursive' calls to this, we have already read and processed the
+ // binder from the transaction data and taken reference counts into account,
+ // so it is cached here.
+ sp<IBinder> targetRef;
+processTransactInternalTailCall:
+
if (transactionData.size() < sizeof(RpcWireTransaction)) {
ALOGE("Expecting %zu but got %zu bytes for RpcWireTransaction. Terminating!",
sizeof(RpcWireTransaction), transactionData.size());
- terminate();
+ (void)session->shutdownAndWait(false);
return BAD_VALUE;
}
RpcWireTransaction* transaction = reinterpret_cast<RpcWireTransaction*>(transactionData.data());
@@ -523,49 +673,73 @@
// TODO(b/182939933): heap allocation just for lookup in mNodeForAddress,
// maybe add an RpcAddress 'view' if the type remains 'heavy'
auto addr = RpcAddress::fromRawEmbedded(&transaction->address);
+ bool oneway = transaction->flags & IBinder::FLAG_ONEWAY;
status_t replyStatus = OK;
sp<IBinder> target;
if (!addr.isZero()) {
- std::lock_guard<std::mutex> _l(mNodeMutex);
-
- auto it = mNodeForAddress.find(addr);
- if (it == mNodeForAddress.end()) {
- ALOGE("Unknown binder address %s.", addr.toString().c_str());
- replyStatus = BAD_VALUE;
+ if (!targetRef) {
+ replyStatus = onBinderEntering(session, addr, &target);
} else {
- target = it->second.binder.promote();
- if (target == nullptr) {
- // This can happen if the binder is remote in this process, and
- // another thread has called the last decStrong on this binder.
- // However, for local binders, it indicates a misbehaving client
- // (any binder which is being transacted on should be holding a
- // strong ref count), so in either case, terminating the
- // session.
- ALOGE("While transacting, binder has been deleted at address %s. Terminating!",
+ target = targetRef;
+ }
+
+ if (replyStatus != OK) {
+ // do nothing
+ } else if (target == nullptr) {
+ // This can happen if the binder is remote in this process, and
+ // another thread has called the last decStrong on this binder.
+ // However, for local binders, it indicates a misbehaving client
+ // (any binder which is being transacted on should be holding a
+ // strong ref count), so in either case, terminating the
+ // session.
+ ALOGE("While transacting, binder has been deleted at address %s. Terminating!",
+ addr.toString().c_str());
+ (void)session->shutdownAndWait(false);
+ replyStatus = BAD_VALUE;
+ } else if (target->localBinder() == nullptr) {
+ ALOGE("Unknown binder address or non-local binder, not address %s. Terminating!",
+ addr.toString().c_str());
+ (void)session->shutdownAndWait(false);
+ replyStatus = BAD_VALUE;
+ } else if (oneway) {
+ std::unique_lock<std::mutex> _l(mNodeMutex);
+ auto it = mNodeForAddress.find(addr);
+ if (it->second.binder.promote() != target) {
+ ALOGE("Binder became invalid during transaction. Bad client? %s",
addr.toString().c_str());
- terminate();
replyStatus = BAD_VALUE;
- } else if (target->localBinder() == nullptr) {
- ALOGE("Transactions can only go to local binders, not address %s. Terminating!",
- addr.toString().c_str());
- terminate();
- replyStatus = BAD_VALUE;
- } else if (transaction->flags & IBinder::FLAG_ONEWAY) {
- if (transaction->asyncNumber != it->second.asyncNumber) {
- // we need to process some other asynchronous transaction
- // first
- // TODO(b/183140903): limit enqueues/detect overfill for bad client
- // TODO(b/183140903): detect when an object is deleted when it still has
- // pending async transactions
- it->second.asyncTodo.push(BinderNode::AsyncTodo{
- .data = std::move(transactionData),
- .asyncNumber = transaction->asyncNumber,
- });
- LOG_RPC_DETAIL("Enqueuing %" PRId64 " on %s", transaction->asyncNumber,
- addr.toString().c_str());
- return OK;
+ } else if (transaction->asyncNumber != it->second.asyncNumber) {
+ // we need to process some other asynchronous transaction
+ // first
+ it->second.asyncTodo.push(BinderNode::AsyncTodo{
+ .ref = target,
+ .data = std::move(transactionData),
+ .asyncNumber = transaction->asyncNumber,
+ });
+
+ size_t numPending = it->second.asyncTodo.size();
+ LOG_RPC_DETAIL("Enqueuing %" PRId64 " on %s (%zu pending)",
+ transaction->asyncNumber, addr.toString().c_str(), numPending);
+
+ constexpr size_t kArbitraryOnewayCallTerminateLevel = 10000;
+ constexpr size_t kArbitraryOnewayCallWarnLevel = 1000;
+ constexpr size_t kArbitraryOnewayCallWarnPer = 1000;
+
+ if (numPending >= kArbitraryOnewayCallWarnLevel) {
+ if (numPending >= kArbitraryOnewayCallTerminateLevel) {
+ ALOGE("WARNING: %zu pending oneway transactions. Terminating!", numPending);
+ _l.unlock();
+ (void)session->shutdownAndWait(false);
+ return FAILED_TRANSACTION;
+ }
+
+ if (numPending % kArbitraryOnewayCallWarnPer == 0) {
+ ALOGW("Warning: many oneway transactions built up on %p (%zu)",
+ target.get(), numPending);
+ }
}
+ return OK;
}
}
}
@@ -585,43 +759,48 @@
data.markForRpc(session);
if (target) {
+ bool origAllowNested = connection->allowNested;
+ connection->allowNested = !oneway;
+
replyStatus = target->transact(transaction->code, data, &reply, transaction->flags);
+
+ connection->allowNested = origAllowNested;
} else {
LOG_RPC_DETAIL("Got special transaction %u", transaction->code);
- sp<RpcServer> server = session->server().promote();
- if (server) {
- // special case for 'zero' address (special server commands)
- switch (transaction->code) {
- case RPC_SPECIAL_TRANSACT_GET_ROOT: {
- replyStatus = reply.writeStrongBinder(server->getRootObject());
- break;
- }
- case RPC_SPECIAL_TRANSACT_GET_MAX_THREADS: {
- replyStatus = reply.writeInt32(server->getMaxThreads());
- break;
- }
- case RPC_SPECIAL_TRANSACT_GET_SESSION_ID: {
- // only sessions w/ services can be the source of a
- // session ID (so still guarded by non-null server)
- //
- // sessions associated with servers must have an ID
- // (hence abort)
- int32_t id = session->getPrivateAccessorForId().get().value();
- replyStatus = reply.writeInt32(id);
- break;
- }
- default: {
- replyStatus = UNKNOWN_TRANSACTION;
+ switch (transaction->code) {
+ case RPC_SPECIAL_TRANSACT_GET_MAX_THREADS: {
+ replyStatus = reply.writeInt32(session->getMaxThreads());
+ break;
+ }
+ case RPC_SPECIAL_TRANSACT_GET_SESSION_ID: {
+ // for client connections, this should always report the value
+ // originally returned from the server, so this is asserting
+ // that it exists
+ replyStatus = session->mId.value().writeToParcel(&reply);
+ break;
+ }
+ default: {
+ sp<RpcServer> server = session->server();
+ if (server) {
+ switch (transaction->code) {
+ case RPC_SPECIAL_TRANSACT_GET_ROOT: {
+ replyStatus = reply.writeStrongBinder(server->getRootObject());
+ break;
+ }
+ default: {
+ replyStatus = UNKNOWN_TRANSACTION;
+ }
+ }
+ } else {
+ ALOGE("Special command sent, but no server object attached.");
}
}
- } else {
- ALOGE("Special command sent, but no server object attached.");
}
}
}
- if (transaction->flags & IBinder::FLAG_ONEWAY) {
+ if (oneway) {
if (replyStatus != OK) {
ALOGW("Oneway call failed with error: %d", replyStatus);
}
@@ -645,13 +824,11 @@
// last refcount dropped after this transaction happened
if (it == mNodeForAddress.end()) return OK;
- // note - only updated now, instead of later, so that other threads
- // will queue any later transactions
-
- // TODO(b/183140903): support > 2**64 async transactions
- // (we can do this by allowing asyncNumber to wrap, since we
- // don't expect more than 2**64 simultaneous transactions)
- it->second.asyncNumber++;
+ if (!nodeProgressAsyncNumber(&it->second)) {
+ _l.unlock();
+ (void)session->shutdownAndWait(false);
+ return DEAD_OBJECT;
+ }
if (it->second.asyncTodo.size() == 0) return OK;
if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) {
@@ -659,64 +836,63 @@
it->second.asyncNumber, addr.toString().c_str());
// justification for const_cast (consider avoiding priority_queue):
- // - AsyncTodo operator< doesn't depend on 'data' object
+ // - AsyncTodo operator< doesn't depend on 'data' or 'ref' objects
// - gotta go fast
- CommandData data = std::move(
- const_cast<BinderNode::AsyncTodo&>(it->second.asyncTodo.top()).data);
+ auto& todo = const_cast<BinderNode::AsyncTodo&>(it->second.asyncTodo.top());
+
+ // reset up arguments
+ transactionData = std::move(todo.data);
+ targetRef = std::move(todo.ref);
+
it->second.asyncTodo.pop();
- _l.unlock();
- return processTransactInternal(fd, session, std::move(data));
+ goto processTransactInternalTailCall;
}
}
return OK;
}
+ LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+ sizeof(RpcWireReply) <
+ reply.dataSize(),
+ "Too much data for reply %zu", reply.dataSize());
+
+ RpcWireHeader cmdReply{
+ .command = RPC_COMMAND_REPLY,
+ .bodySize = static_cast<uint32_t>(sizeof(RpcWireReply) + reply.dataSize()),
+ };
RpcWireReply rpcReply{
.status = replyStatus,
};
- CommandData replyData(sizeof(RpcWireReply) + reply.dataSize());
+ CommandData replyData(sizeof(RpcWireHeader) + sizeof(RpcWireReply) + reply.dataSize());
if (!replyData.valid()) {
return NO_MEMORY;
}
- memcpy(replyData.data() + 0, &rpcReply, sizeof(RpcWireReply));
- memcpy(replyData.data() + sizeof(RpcWireReply), reply.data(), reply.dataSize());
+ memcpy(replyData.data() + 0, &cmdReply, sizeof(RpcWireHeader));
+ memcpy(replyData.data() + sizeof(RpcWireHeader), &rpcReply, sizeof(RpcWireReply));
+ memcpy(replyData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireReply), reply.data(),
+ reply.dataSize());
- if (replyData.size() > std::numeric_limits<uint32_t>::max()) {
- ALOGE("Reply size too big %zu", transactionData.size());
- terminate();
- return BAD_VALUE;
- }
-
- RpcWireHeader cmdReply{
- .command = RPC_COMMAND_REPLY,
- .bodySize = static_cast<uint32_t>(replyData.size()),
- };
-
- if (!rpcSend(fd, "reply header", &cmdReply, sizeof(RpcWireHeader))) {
- return DEAD_OBJECT;
- }
- if (!rpcSend(fd, "reply body", replyData.data(), replyData.size())) {
- return DEAD_OBJECT;
- }
- return OK;
+ return rpcSend(connection, session, "reply", replyData.data(), replyData.size());
}
-status_t RpcState::processDecStrong(const base::unique_fd& fd, const RpcWireHeader& command) {
+status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const RpcWireHeader& command) {
LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_DEC_STRONG, "command: %d", command.command);
CommandData commandData(command.bodySize);
if (!commandData.valid()) {
return NO_MEMORY;
}
- if (!rpcRec(fd, "dec ref body", commandData.data(), commandData.size())) {
- return DEAD_OBJECT;
- }
+ if (status_t status =
+ rpcRec(connection, session, "dec ref body", commandData.data(), commandData.size());
+ status != OK)
+ return status;
if (command.bodySize < sizeof(RpcWireAddress)) {
ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireAddress. Terminating!",
sizeof(RpcWireAddress), command.bodySize);
- terminate();
+ (void)session->shutdownAndWait(false);
return BAD_VALUE;
}
RpcWireAddress* address = reinterpret_cast<RpcWireAddress*>(commandData.data());
@@ -734,7 +910,8 @@
if (target == nullptr) {
ALOGE("While requesting dec strong, binder has been deleted at address %s. Terminating!",
addr.toString().c_str());
- terminate();
+ _l.unlock();
+ (void)session->shutdownAndWait(false);
return BAD_VALUE;
}
@@ -746,22 +923,39 @@
LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s",
addr.toString().c_str());
- sp<IBinder> tempHold;
-
it->second.timesSent--;
- if (it->second.timesSent == 0) {
- tempHold = it->second.sentRef;
- it->second.sentRef = nullptr;
-
- if (it->second.timesRecd == 0) {
- mNodeForAddress.erase(it);
- }
- }
-
+ sp<IBinder> tempHold = tryEraseNode(it);
_l.unlock();
tempHold = nullptr; // destructor may make binder calls on this session
return OK;
}
+sp<IBinder> RpcState::tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it) {
+ sp<IBinder> ref;
+
+ if (it->second.timesSent == 0) {
+ ref = std::move(it->second.sentRef);
+
+ if (it->second.timesRecd == 0) {
+ LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
+ "Can't delete binder w/ pending async transactions");
+ mNodeForAddress.erase(it);
+ }
+ }
+
+ return ref;
+}
+
+bool RpcState::nodeProgressAsyncNumber(BinderNode* node) {
+ // 2**64 =~ 10**19 =~ 1000 transactions per second for 585 million years to
+ // a single binder
+ if (node->asyncNumber >= std::numeric_limits<decltype(node->asyncNumber)>::max()) {
+ ALOGE("Out of async transaction IDs. Terminating");
+ return false;
+ }
+ node->asyncNumber++;
+ return true;
+}
+
} // namespace android
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index 31f8a22..5ac0b97 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -42,6 +42,15 @@
#define LOG_RPC_DETAIL(...) ALOGV(__VA_ARGS__) // for type checking
#endif
+#define RPC_FLAKE_PRONE false
+
+#if RPC_FLAKE_PRONE
+void rpcMaybeWaitToFlake();
+#define MAYBE_WAIT_IN_FLAKE_MODE rpcMaybeWaitToFlake()
+#else
+#define MAYBE_WAIT_IN_FLAKE_MODE do {} while (false)
+#endif
+
/**
* Abstracts away management of ref counts and the wire format from
* RpcSession
@@ -51,19 +60,37 @@
RpcState();
~RpcState();
- // TODO(b/182940634): combine some special transactions into one "getServerInfo" call?
- sp<IBinder> getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session);
- status_t getMaxThreads(const base::unique_fd& fd, const sp<RpcSession>& session,
- size_t* maxThreadsOut);
- status_t getSessionId(const base::unique_fd& fd, const sp<RpcSession>& session,
- int32_t* sessionIdOut);
+ status_t sendConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session);
+ status_t readConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session);
- [[nodiscard]] status_t transact(const base::unique_fd& fd, const RpcAddress& address,
- uint32_t code, const Parcel& data,
+ // TODO(b/182940634): combine some special transactions into one "getServerInfo" call?
+ sp<IBinder> getRootObject(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session);
+ status_t getMaxThreads(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, size_t* maxThreadsOut);
+ status_t getSessionId(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, RpcAddress* sessionIdOut);
+
+ [[nodiscard]] status_t transact(const sp<RpcSession::RpcConnection>& connection,
+ const sp<IBinder>& address, uint32_t code, const Parcel& data,
const sp<RpcSession>& session, Parcel* reply, uint32_t flags);
- [[nodiscard]] status_t sendDecStrong(const base::unique_fd& fd, const RpcAddress& address);
- [[nodiscard]] status_t getAndExecuteCommand(const base::unique_fd& fd,
- const sp<RpcSession>& session);
+ [[nodiscard]] status_t transactAddress(const sp<RpcSession::RpcConnection>& connection,
+ const RpcAddress& address, uint32_t code,
+ const Parcel& data, const sp<RpcSession>& session,
+ Parcel* reply, uint32_t flags);
+ [[nodiscard]] status_t sendDecStrong(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const RpcAddress& address);
+
+ enum class CommandType {
+ ANY,
+ CONTROL_ONLY,
+ };
+ [[nodiscard]] status_t getAndExecuteCommand(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, CommandType type);
+ [[nodiscard]] status_t drainCommands(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, CommandType type);
/**
* Called by Parcel for outgoing binders. This implies one refcount of
@@ -77,12 +104,12 @@
* to the process, if this process already has one, or it takes ownership of
* that refcount
*/
- sp<IBinder> onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address);
+ [[nodiscard]] status_t onBinderEntering(const sp<RpcSession>& session,
+ const RpcAddress& address, sp<IBinder>* out);
size_t countBinders();
void dump();
-private:
/**
* Called when reading or writing data to a session fails to clean up
* data associated with the session in order to cleanup binders.
@@ -99,7 +126,10 @@
* WARNING: RpcState is responsible for calling this when the session is
* no longer recoverable.
*/
- void terminate();
+ void clear();
+
+private:
+ void dumpLocked();
// Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
// large allocations to avoid being requested from allocating too much data.
@@ -115,21 +145,26 @@
size_t mSize;
};
- [[nodiscard]] bool rpcSend(const base::unique_fd& fd, const char* what, const void* data,
- size_t size);
- [[nodiscard]] bool rpcRec(const base::unique_fd& fd, const char* what, void* data, size_t size);
+ [[nodiscard]] status_t rpcSend(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const char* what,
+ const void* data, size_t size);
+ [[nodiscard]] status_t rpcRec(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, const char* what, void* data,
+ size_t size);
- [[nodiscard]] status_t waitForReply(const base::unique_fd& fd, const sp<RpcSession>& session,
- Parcel* reply);
- [[nodiscard]] status_t processServerCommand(const base::unique_fd& fd,
- const sp<RpcSession>& session,
- const RpcWireHeader& command);
- [[nodiscard]] status_t processTransact(const base::unique_fd& fd, const sp<RpcSession>& session,
+ [[nodiscard]] status_t waitForReply(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session, Parcel* reply);
+ [[nodiscard]] status_t processCommand(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session,
+ const RpcWireHeader& command, CommandType type);
+ [[nodiscard]] status_t processTransact(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session,
const RpcWireHeader& command);
- [[nodiscard]] status_t processTransactInternal(const base::unique_fd& fd,
+ [[nodiscard]] status_t processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
const sp<RpcSession>& session,
CommandData transactionData);
- [[nodiscard]] status_t processDecStrong(const base::unique_fd& fd,
+ [[nodiscard]] status_t processDecStrong(const sp<RpcSession::RpcConnection>& connection,
+ const sp<RpcSession>& session,
const RpcWireHeader& command);
struct BinderNode {
@@ -163,6 +198,7 @@
// async transaction queue, _only_ for local binder
struct AsyncTodo {
+ sp<IBinder> ref;
CommandData data;
uint64_t asyncNumber = 0;
@@ -179,6 +215,15 @@
// (no additional data specific to remote binders)
};
+ // checks if there is any reference left to a node and erases it. If erase
+ // happens, and there is a strong reference to the binder kept by
+ // binderNode, this returns that strong reference, so that it can be
+ // dropped after any locks are removed.
+ sp<IBinder> tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it);
+ // true - success
+ // false - session shutdown, halt
+ [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node);
+
std::mutex mNodeMutex;
bool mTerminated = false;
// binders known by both sides of a session
diff --git a/libs/binder/RpcWireFormat.h b/libs/binder/RpcWireFormat.h
index c5fa008..2a44c7a 100644
--- a/libs/binder/RpcWireFormat.h
+++ b/libs/binder/RpcWireFormat.h
@@ -20,6 +20,40 @@
#pragma clang diagnostic push
#pragma clang diagnostic error "-Wpadded"
+enum : uint8_t {
+ RPC_CONNECTION_OPTION_INCOMING = 0x1, // default is outgoing
+};
+
+constexpr uint64_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address
+constexpr uint64_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1;
+
+struct RpcWireAddress {
+ uint64_t options;
+ uint8_t address[32];
+};
+
+/**
+ * This is sent to an RpcServer in order to request a new connection is created,
+ * either as part of a new session or an existing session
+ */
+struct RpcConnectionHeader {
+ RpcWireAddress sessionId;
+ uint8_t options;
+ uint8_t reserved[7];
+};
+
+#define RPC_CONNECTION_INIT_OKAY "cci"
+
+/**
+ * Whenever a client connection is setup, this is sent as the initial
+ * transaction. The main use of this is in order to control the timing for when
+ * an incoming connection is setup.
+ */
+struct RpcOutgoingConnectionInit {
+ char msg[4];
+ uint8_t reserved[4];
+};
+
enum : uint32_t {
/**
* follows is RpcWireTransaction, if flags != oneway, reply w/ RPC_COMMAND_REPLY expected
@@ -51,8 +85,6 @@
RPC_SPECIAL_TRANSACT_GET_SESSION_ID = 2,
};
-constexpr int32_t RPC_SESSION_ID_NEW = -1;
-
// serialization is like:
// |RpcWireHeader|struct desginated by 'command'| (over and over again)
@@ -63,10 +95,6 @@
uint32_t reserved[2];
};
-struct RpcWireAddress {
- uint8_t address[32];
-};
-
struct RpcWireTransaction {
RpcWireAddress address;
uint32_t code;
diff --git a/libs/binder/ServiceManagerHost.cpp b/libs/binder/ServiceManagerHost.cpp
new file mode 100644
index 0000000..1c2f9b4
--- /dev/null
+++ b/libs/binder/ServiceManagerHost.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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 "ServiceManagerHost.h"
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
+
+#include "UtilsHost.h"
+
+namespace android {
+
+namespace {
+
+const void* kDeviceServiceExtraId = "DeviceServiceExtra";
+
+// Parse stdout of program execution to string. If any error, return 0.
+unsigned int parsePortNumber(const std::string& out, const std::string& what) {
+ auto trimmed = android::base::Trim(out);
+ unsigned int port = 0;
+ if (!android::base::ParseUint(trimmed, &port)) {
+ int savedErrno = errno;
+ ALOGE("%s is not a valid %s: %s", trimmed.c_str(), what.c_str(), strerror(savedErrno));
+ return 0;
+ }
+ if (port == 0) {
+ ALOGE("0 is not a valid %s", what.c_str());
+ return 0; // explicitly
+ }
+ return port;
+}
+
+// RAII object for adb forwarding
+class AdbForwarder {
+public:
+ AdbForwarder() = default;
+ static std::optional<AdbForwarder> forward(unsigned int devicePort);
+ AdbForwarder(AdbForwarder&& other) noexcept { (*this) = std::move(other); }
+ AdbForwarder& operator=(AdbForwarder&&) noexcept;
+ ~AdbForwarder();
+ [[nodiscard]] const std::optional<unsigned int>& hostPort() const { return mPort; }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AdbForwarder);
+ explicit AdbForwarder(unsigned int port) : mPort(port) {}
+ std::optional<unsigned int> mPort;
+};
+std::optional<AdbForwarder> AdbForwarder::forward(unsigned int devicePort) {
+ auto result =
+ execute({"adb", "forward", "tcp:0", "tcp:" + std::to_string(devicePort)}, nullptr);
+ if (!result.ok()) {
+ ALOGE("Unable to run `adb forward tcp:0 tcp:%d`: %s", devicePort,
+ result.error().message().c_str());
+ return std::nullopt;
+ }
+ // Must end with exit code 0 (`has_value() && value() == 0`)
+ if (result->exitCode.value_or(1) != 0) {
+ ALOGE("Unable to run `adb forward tcp:0 tcp:%d`, command exits with %s", devicePort,
+ result->toString().c_str());
+ return std::nullopt;
+ }
+ if (!result->stderr.empty()) {
+ LOG_HOST("`adb forward tcp:0 tcp:%d` writes to stderr: %s", devicePort,
+ result->stderr.c_str());
+ }
+
+ unsigned int hostPort = parsePortNumber(result->stdout, "host port");
+ if (hostPort == 0) return std::nullopt;
+
+ return AdbForwarder(hostPort);
+}
+
+AdbForwarder& AdbForwarder::operator=(AdbForwarder&& other) noexcept {
+ std::swap(mPort, other.mPort);
+ return *this;
+}
+
+AdbForwarder::~AdbForwarder() {
+ if (!mPort.has_value()) return;
+
+ auto result = execute({"adb", "forward", "--remove", "tcp:" + std::to_string(*mPort)}, nullptr);
+ if (!result.ok()) {
+ ALOGE("Unable to run `adb forward --remove tcp:%d`: %s", *mPort,
+ result.error().message().c_str());
+ return;
+ }
+ // Must end with exit code 0 (`has_value() && value() == 0`)
+ if (result->exitCode.value_or(1) != 0) {
+ ALOGE("Unable to run `adb forward --remove tcp:%d`, command exits with %s", *mPort,
+ result->toString().c_str());
+ return;
+ }
+ if (!result->stderr.empty()) {
+ LOG_HOST("`adb forward --remove tcp:%d` writes to stderr: %s", *mPort,
+ result->stderr.c_str());
+ }
+
+ LOG_HOST("Successfully run `adb forward --remove tcp:%d`", *mPort);
+}
+
+void cleanupCommandResult(const void* id, void* obj, void* /* cookie */) {
+ LOG_ALWAYS_FATAL_IF(id != kDeviceServiceExtraId,
+ "cleanupCommandResult invoked with mismatched ID %p, "
+ "expected %p",
+ id, kDeviceServiceExtraId);
+ auto ptr = static_cast<CommandResult*>(obj);
+ delete ptr;
+}
+
+} // namespace
+
+sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) {
+ std::vector<std::string> prefix{"adb", "shell", "servicedispatcher"};
+ serviceDispatcherArgs.insert(serviceDispatcherArgs.begin(), prefix.begin(), prefix.end());
+
+ auto result = execute(std::move(serviceDispatcherArgs), &CommandResult::stdoutEndsWithNewLine);
+ if (!result.ok()) {
+ ALOGE("%s", result.error().message().c_str());
+ return nullptr;
+ }
+
+ // `servicedispatcher` process must be alive to keep the port open.
+ if (result->exitCode.has_value()) {
+ ALOGE("Command exits with: %s", result->toString().c_str());
+ return nullptr;
+ }
+ if (!result->stderr.empty()) {
+ LOG_HOST("servicedispatcher writes to stderr: %s", result->stderr.c_str());
+ }
+
+ if (!result->stdoutEndsWithNewLine()) {
+ ALOGE("Unexpected command result: %s", result->toString().c_str());
+ return nullptr;
+ }
+
+ unsigned int devicePort = parsePortNumber(result->stdout, "device port");
+ if (devicePort == 0) return nullptr;
+
+ auto forwardResult = AdbForwarder::forward(devicePort);
+ if (!forwardResult.has_value()) {
+ return nullptr;
+ }
+ LOG_ALWAYS_FATAL_IF(!forwardResult->hostPort().has_value());
+
+ auto rpcSession = RpcSession::make();
+ if (!rpcSession->setupInetClient("127.0.0.1", *forwardResult->hostPort())) {
+ ALOGE("Unable to set up inet client on host port %u", *forwardResult->hostPort());
+ return nullptr;
+ }
+ auto binder = rpcSession->getRootObject();
+ if (binder == nullptr) {
+ ALOGE("RpcSession::getRootObject returns nullptr");
+ return nullptr;
+ }
+
+ LOG_ALWAYS_FATAL_IF(
+ nullptr !=
+ binder->attachObject(kDeviceServiceExtraId,
+ static_cast<void*>(new CommandResult(std::move(*result))), nullptr,
+ &cleanupCommandResult));
+ return binder;
+}
+
+} // namespace android
diff --git a/libs/binder/ServiceManagerHost.h b/libs/binder/ServiceManagerHost.h
new file mode 100644
index 0000000..e59724c
--- /dev/null
+++ b/libs/binder/ServiceManagerHost.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <android-base/macros.h>
+#include <android/os/IServiceManager.h>
+
+namespace android {
+
+// Get a service on device by running servicedispatcher with the given args, e.g.
+// getDeviceService({"foo"});
+// Return nullptr on any error.
+// When the returned binder object is destroyed, remove adb forwarding and kills
+// the long-running servicedispatcher process.
+sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs);
+
+} // namespace android
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index f12ef4e..00b69d5 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -33,7 +33,6 @@
Stability::Category Stability::Category::currentFromLevel(Level level) {
return {
.version = kBinderWireFormatVersion,
- .reserved = {0},
.level = level,
};
}
@@ -79,9 +78,9 @@
LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}
-void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& binder) {
+std::string Stability::debugToString(const sp<IBinder>& binder) {
auto stability = getCategory(binder.get());
- ALOGE("%s: stability is %s", tag.c_str(), stability.debugString().c_str());
+ return stability.debugString();
}
void Stability::markVndk(IBinder* binder) {
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index b5a078c..a44c578 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -130,13 +130,13 @@
}
// The remote threw an exception. Get the message back.
- String16 message;
+ std::optional<String16> message;
status = parcel.readString16(&message);
if (status != OK) {
setFromStatusT(status);
return status;
}
- mMessage = String8(message);
+ mMessage = String8(message.value_or(String16()));
// Skip over the remote stack trace data
int32_t remote_stack_trace_header_size;
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 1010a2d..9c5ce67 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -16,10 +16,13 @@
"name": "binderDriverInterfaceTest"
},
{
+ "name": "binderHostDeviceTest"
+ },
+ {
"name": "binderTextOutputTest"
},
{
- "name": "binderParcelTest"
+ "name": "binderUnitTest"
},
{
"name": "binderLibTest"
@@ -31,6 +34,9 @@
"name": "binderStabilityTest"
},
{
+ "name": "binderUtilsHostTest"
+ },
+ {
"name": "libbinder_ndk_unit_test"
},
{
diff --git a/libs/binder/UtilsHost.cpp b/libs/binder/UtilsHost.cpp
new file mode 100644
index 0000000..d121ce2
--- /dev/null
+++ b/libs/binder/UtilsHost.cpp
@@ -0,0 +1,177 @@
+/*
+ * 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 "UtilsHost.h"
+
+#include <poll.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <sstream>
+
+#include <log/log.h>
+
+namespace android {
+
+CommandResult::~CommandResult() {
+ if (!pid.has_value()) return;
+ if (*pid == 0) {
+ ALOGW("%s: PID is unexpectedly 0, won't kill it", __PRETTY_FUNCTION__);
+ return;
+ }
+
+ ALOGE_IF(kill(*pid, SIGKILL) != 0, "kill(%d): %s", *pid, strerror(errno));
+
+ while (pid.has_value()) {
+ int status;
+ LOG_HOST("%s: Waiting for PID %d to exit.", __PRETTY_FUNCTION__, *pid);
+ int waitres = waitpid(*pid, &status, 0);
+ if (waitres == -1) {
+ ALOGE("%s: waitpid(%d): %s", __PRETTY_FUNCTION__, *pid, strerror(errno));
+ break;
+ }
+ if (WIFEXITED(status)) {
+ LOG_HOST("%s: PID %d exited.", __PRETTY_FUNCTION__, *pid);
+ pid.reset();
+ } else if (WIFSIGNALED(status)) {
+ LOG_HOST("%s: PID %d terminated by signal %d.", __PRETTY_FUNCTION__, *pid,
+ WTERMSIG(status));
+ pid.reset();
+ } else if (WIFSTOPPED(status)) {
+ ALOGW("%s: pid %d stopped", __PRETTY_FUNCTION__, *pid);
+ } else if (WIFCONTINUED(status)) {
+ ALOGW("%s: pid %d continued", __PRETTY_FUNCTION__, *pid);
+ }
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const CommandResult& res) {
+ if (res.exitCode) os << "code=" << *res.exitCode;
+ if (res.signal) os << "signal=" << *res.signal;
+ if (res.pid) os << ", pid=" << *res.pid;
+ return os << ", stdout=" << res.stdout << ", stderr=" << res.stderr;
+}
+
+std::string CommandResult::toString() const {
+ std::stringstream ss;
+ ss << (*this);
+ return ss.str();
+}
+
+android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
+ const std::function<bool(const CommandResult&)>& end) {
+ // turn vector<string> into null-terminated char* vector.
+ std::vector<char*> argv;
+ argv.reserve(argStringVec.size() + 1);
+ for (auto& arg : argStringVec) argv.push_back(arg.data());
+ argv.push_back(nullptr);
+
+ CommandResult ret;
+ android::base::unique_fd outWrite;
+ if (!android::base::Pipe(&ret.outPipe, &outWrite))
+ return android::base::ErrnoError() << "pipe() for outPipe";
+ android::base::unique_fd errWrite;
+ if (!android::base::Pipe(&ret.errPipe, &errWrite))
+ return android::base::ErrnoError() << "pipe() for errPipe";
+
+ int pid = fork();
+ if (pid == -1) return android::base::ErrnoError() << "fork()";
+ if (pid == 0) {
+ // child
+ ret.outPipe.reset();
+ ret.errPipe.reset();
+
+ int res = TEMP_FAILURE_RETRY(dup2(outWrite.get(), STDOUT_FILENO));
+ LOG_ALWAYS_FATAL_IF(-1 == res, "dup2(outPipe): %s", strerror(errno));
+ outWrite.reset();
+
+ res = TEMP_FAILURE_RETRY(dup2(errWrite.get(), STDERR_FILENO));
+ LOG_ALWAYS_FATAL_IF(-1 == res, "dup2(errPipe): %s", strerror(errno));
+ errWrite.reset();
+
+ execvp(argv[0], argv.data());
+ LOG_ALWAYS_FATAL("execvp() returns");
+ }
+ // parent
+ outWrite.reset();
+ errWrite.reset();
+ ret.pid = pid;
+
+ auto handlePoll = [](android::base::unique_fd* fd, const pollfd* pfd, std::string* s) {
+ if (!fd->ok()) return true;
+ if (pfd->revents & POLLIN) {
+ char buf[1024];
+ ssize_t n = TEMP_FAILURE_RETRY(read(fd->get(), buf, sizeof(buf)));
+ if (n < 0) return false;
+ if (n > 0) *s += std::string_view(buf, n);
+ }
+ if (pfd->revents & POLLHUP) {
+ fd->reset();
+ }
+ return true;
+ };
+
+ // Drain both stdout and stderr. Check end() regularly until both are closed.
+ while (ret.outPipe.ok() || ret.errPipe.ok()) {
+ pollfd fds[2];
+ pollfd *outPollFd = nullptr, *errPollFd = nullptr;
+ memset(fds, 0, sizeof(fds));
+ nfds_t nfds = 0;
+ if (ret.outPipe.ok()) {
+ outPollFd = &fds[nfds++];
+ *outPollFd = {.fd = ret.outPipe.get(), .events = POLLIN};
+ }
+ if (ret.errPipe.ok()) {
+ errPollFd = &fds[nfds++];
+ *errPollFd = {.fd = ret.errPipe.get(), .events = POLLIN};
+ }
+ int pollRet = poll(fds, nfds, 1000 /* ms timeout */);
+ if (pollRet == -1) return android::base::ErrnoError() << "poll()";
+
+ if (!handlePoll(&ret.outPipe, outPollFd, &ret.stdout))
+ return android::base::ErrnoError() << "read(stdout)";
+ if (!handlePoll(&ret.errPipe, errPollFd, &ret.stderr))
+ return android::base::ErrnoError() << "read(stderr)";
+
+ if (end && end(ret)) return ret;
+ }
+
+ // If both stdout and stderr are closed by the subprocess, it may or may not be terminated.
+ while (ret.pid.has_value()) {
+ int status;
+ auto exitPid = waitpid(pid, &status, 0);
+ if (exitPid == -1) return android::base::ErrnoError() << "waitpid(" << pid << ")";
+ if (exitPid == pid) {
+ if (WIFEXITED(status)) {
+ ret.pid = std::nullopt;
+ ret.exitCode = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ ret.pid = std::nullopt;
+ ret.signal = WTERMSIG(status);
+ } else if (WIFSTOPPED(status)) {
+ ALOGW("%s: pid %d stopped", __PRETTY_FUNCTION__, *ret.pid);
+ } else if (WIFCONTINUED(status)) {
+ ALOGW("%s: pid %d continued", __PRETTY_FUNCTION__, *ret.pid);
+ }
+ }
+ // ret is not changed unless the process is terminated (where pid == nullopt). Hence there
+ // is no need to check the predicate `end(ret)`.
+ }
+
+ return ret;
+}
+} // namespace android
diff --git a/libs/binder/UtilsHost.h b/libs/binder/UtilsHost.h
new file mode 100644
index 0000000..0f29f60
--- /dev/null
+++ b/libs/binder/UtilsHost.h
@@ -0,0 +1,99 @@
+/*
+ * 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 <optional>
+#include <ostream>
+#include <string>
+#include <variant>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+/**
+ * Log a lot more information about host-device binder communication, when debugging issues.
+ */
+#define SHOULD_LOG_HOST false
+
+#if SHOULD_LOG_HOST
+#define LOG_HOST(...) ALOGI(__VA_ARGS__)
+#else
+#define LOG_HOST(...) ALOGV(__VA_ARGS__) // for type checking
+#endif
+
+namespace android {
+
+struct CommandResult {
+ std::optional<int32_t> exitCode;
+ std::optional<int32_t> signal;
+ std::optional<pid_t> pid;
+ std::string stdout;
+ std::string stderr;
+
+ android::base::unique_fd outPipe;
+ android::base::unique_fd errPipe;
+
+ CommandResult() = default;
+ CommandResult(CommandResult&& other) noexcept { (*this) = std::move(other); }
+ CommandResult& operator=(CommandResult&& other) noexcept {
+ std::swap(exitCode, other.exitCode);
+ std::swap(signal, other.signal);
+ std::swap(pid, other.pid);
+ std::swap(stdout, other.stdout);
+ std::swap(stderr, other.stderr);
+ return *this;
+ }
+ ~CommandResult();
+ [[nodiscard]] std::string toString() const;
+
+ [[nodiscard]] bool stdoutEndsWithNewLine() const {
+ return !stdout.empty() && stdout.back() == '\n';
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(CommandResult);
+};
+
+std::ostream& operator<<(std::ostream& os, const CommandResult& res);
+
+// Execute a command using tokens specified in @a argStringVec.
+//
+// @a end is a predicate checked periodically when the command emits any output to stdout or
+// stderr. When it is evaluated to true, the function returns immediately even though
+// the child process has not been terminated. The function also assumes that, after @a end
+// is evaluated to true, the child process does not emit any other messages.
+// If this is not the case, caller to execute() must handle these I/O in the pipes in the returned
+// CommandResult object. Otherwise the child program may hang on I/O.
+//
+// If @a end is nullptr, it is equivalent to a predicate that always returns false. In this
+// case, execute() returns after the child process is terminated.
+//
+// If @a end is evaluated to true, and execute() returns with the child process running,
+// the returned CommandResult has pid, outPipe, and errPipe set. In this case, the caller is
+// responsible for holding the returned CommandResult. When the CommandResult object is destroyed,
+// the child process is killed.
+//
+// On the other hand, execute() returns with the child process terminated, either exitCode or signal
+// is set.
+//
+// If the parent process has encountered any errors for system calls, return ExecuteError with
+// the proper errno set.
+android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
+ const std::function<bool(const CommandResult&)>& end);
+} // namespace android
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 7e9be41..46223bb 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -54,12 +54,11 @@
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = nullptr);
- virtual void attachObject( const void* objectID,
- void* object,
- void* cleanupCookie,
- object_cleanup_func func) final;
+ virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
+ object_cleanup_func func) final;
virtual void* findObject(const void* objectID) const final;
- virtual void detachObject(const void* objectID) final;
+ virtual void* detachObject(const void* objectID) final;
+ void withLock(const std::function<void()>& doWithLock);
virtual BBinder* localBinder();
@@ -94,6 +93,16 @@
pid_t getDebugPid();
+ // Whether this binder has been sent to another process.
+ bool wasParceled();
+ // Consider this binder as parceled (setup/init-related calls should no
+ // longer by called. This is automatically set by when this binder is sent
+ // to another process.
+ void setParceled();
+
+ [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd,
+ const sp<IBinder>& keepAliveBinder);
+
protected:
virtual ~BBinder();
@@ -107,17 +116,24 @@
BBinder(const BBinder& o);
BBinder& operator=(const BBinder& o);
+ class RpcServerLink;
class Extras;
Extras* getOrCreateExtras();
+ [[nodiscard]] status_t setRpcClientDebug(const Parcel& data);
+ void removeRpcServerLink(const sp<RpcServerLink>& link);
+
std::atomic<Extras*> mExtras;
friend ::android::internal::Stability;
- union {
- int32_t mStability;
- void* mReserved0;
- };
+ int16_t mStability;
+ bool mParceled;
+ uint8_t mReserved0;
+
+#ifdef __LP64__
+ int32_t mReserved1;
+#endif
};
// ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BinderService.h b/libs/binder/include/binder/BinderService.h
index 5776f3c..e58d489 100644
--- a/libs/binder/include/binder/BinderService.h
+++ b/libs/binder/include/binder/BinderService.h
@@ -26,6 +26,24 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+// WARNING: deprecated - DO NOT USE - prefer to setup service directly.
+//
+// This class embellishes a class with a few static methods which can be used in
+// limited circumstances (when one service needs to be registered and
+// published). However, this is an anti-pattern:
+// - these methods are aliases of existing methods, and as such, represent an
+// incremental amount of information required to understand the system but
+// which does not actually save in terms of lines of code. For instance, users
+// of this class should be surprised to know that this will start up to 16
+// threads in the binder threadpool.
+// - the template instantiation costs need to be paid, even though everything
+// done here is generic.
+// - the getServiceName API here is undocumented and non-local (for instance,
+// this unnecessarily assumes a single service type will only be instantiated
+// once with no arguments).
+//
+// So, DO NOT USE.
+
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 61bf018..c69bb9e 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -72,12 +72,11 @@
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = nullptr);
- virtual void attachObject( const void* objectID,
- void* object,
- void* cleanupCookie,
- object_cleanup_func func) final;
+ virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
+ object_cleanup_func func) final;
virtual void* findObject(const void* objectID) const final;
- virtual void detachObject(const void* objectID) final;
+ virtual void* detachObject(const void* objectID) final;
+ void withLock(const std::function<void()>& doWithLock);
virtual BpBinder* remoteBinder();
@@ -91,27 +90,23 @@
static void setLimitCallback(binder_proxy_limit_callback cb);
static void setBinderProxyCountWatermarks(int high, int low);
- class ObjectManager
- {
+ class ObjectManager {
public:
- ObjectManager();
- ~ObjectManager();
+ ObjectManager();
+ ~ObjectManager();
- void attach( const void* objectID,
- void* object,
- void* cleanupCookie,
- IBinder::object_cleanup_func func);
- void* find(const void* objectID) const;
- void detach(const void* objectID);
+ void* attach(const void* objectID, void* object, void* cleanupCookie,
+ IBinder::object_cleanup_func func);
+ void* find(const void* objectID) const;
+ void* detach(const void* objectID);
- void kill();
+ void kill();
private:
- ObjectManager(const ObjectManager&);
+ ObjectManager(const ObjectManager&);
ObjectManager& operator=(const ObjectManager&);
- struct entry_t
- {
+ struct entry_t {
void* object;
void* cleanupCookie;
IBinder::object_cleanup_func func;
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 97c826c..43fc5ff 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -22,6 +22,8 @@
#include <utils/String16.h>
#include <utils/Vector.h>
+#include <functional>
+
// linux/binder.h defines this, but we don't want to include it here in order to
// avoid exporting the kernel headers
#ifndef B_PACK_CHARS
@@ -60,6 +62,7 @@
SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
DEBUG_PID_TRANSACTION = B_PACK_CHARS('_', 'P', 'I', 'D'),
+ SET_RPC_CLIENT_TRANSACTION = B_PACK_CHARS('_', 'R', 'P', 'C'),
// See android.os.IBinder.TWEET_TRANSACTION
// Most importantly, messages can be anything not exceeding 130 UTF-8
@@ -152,6 +155,27 @@
*/
status_t getDebugPid(pid_t* outPid);
+ /**
+ * Set the RPC client fd to this binder service, for debugging. This is only available on
+ * debuggable builds.
+ *
+ * When this is called on a binder service, the service:
+ * 1. sets up RPC server
+ * 2. spawns 1 new thread that calls RpcServer::join()
+ * - join() spawns some number of threads that accept() connections; see RpcServer
+ *
+ * setRpcClientDebug() may be called multiple times. Each call will add a new RpcServer
+ * and opens up a TCP port.
+ *
+ * Note: A thread is spawned for each accept()'ed fd, which may call into functions of the
+ * interface freely. See RpcServer::join(). To avoid such race conditions, implement the service
+ * functions with multithreading support.
+ *
+ * On death of @a keepAliveBinder, the RpcServer shuts down.
+ */
+ [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd socketFd,
+ const sp<IBinder>& keepAliveBinder);
+
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t transact( uint32_t code,
const Parcel& data,
@@ -233,26 +257,30 @@
* objects are invoked with their respective objectID, object, and
* cleanupCookie. Access to these APIs can be made from multiple threads,
* but calls from different threads are allowed to be interleaved.
+ *
+ * This returns the object which is already attached. If this returns a
+ * non-null value, it means that attachObject failed (a given objectID can
+ * only be used once).
*/
- virtual void attachObject( const void* objectID,
- void* object,
- void* cleanupCookie,
- object_cleanup_func func) = 0;
+ [[nodiscard]] virtual void* attachObject(const void* objectID, void* object,
+ void* cleanupCookie, object_cleanup_func func) = 0;
/**
* Returns object attached with attachObject.
*/
- virtual void* findObject(const void* objectID) const = 0;
+ [[nodiscard]] virtual void* findObject(const void* objectID) const = 0;
/**
- * WARNING: this API does not call the cleanup function for legacy reasons.
- * It also does not return void* for legacy reasons. If you need to detach
- * an object and destroy it, there are two options:
- * - if you can, don't call detachObject and instead wait for the destructor
- * to clean it up.
- * - manually retrieve and destruct the object (if multiple of your threads
- * are accessing these APIs, you must guarantee that attachObject isn't
- * called after findObject and before detachObject is called).
+ * Returns object attached with attachObject, and detaches it. This does not
+ * delete the object.
*/
- virtual void detachObject(const void* objectID) = 0;
+ [[nodiscard]] virtual void* detachObject(const void* objectID) = 0;
+
+ /**
+ * Use the lock that this binder contains internally. For instance, this can
+ * be used to modify an attached object without needing to add an additional
+ * lock (though, that attached object must be retrieved before calling this
+ * method). Calling (most) IBinder methods inside this will deadlock.
+ */
+ void withLock(const std::function<void()>& doWithLock);
virtual BBinder* localBinder();
virtual BpBinder* remoteBinder();
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 196a41b..20a9f36 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -62,7 +62,7 @@
* call. If not in a binder call, this will return getpid. If the
* call is oneway, this will return 0.
*/
- pid_t getCallingPid() const;
+ [[nodiscard]] pid_t getCallingPid() const;
/**
* Returns the SELinux security identifier of the process which has
@@ -73,13 +73,43 @@
* This can't be restored once it's cleared, and it does not return the
* context of the current process when not in a binder call.
*/
- const char* getCallingSid() const;
+ [[nodiscard]] const char* getCallingSid() const;
/**
* Returns the UID of the process which has made the current binder
* call. If not in a binder call, this will return 0.
*/
- uid_t getCallingUid() const;
+ [[nodiscard]] uid_t getCallingUid() const;
+
+ /**
+ * Make it an abort to rely on getCalling* for a section of
+ * execution.
+ *
+ * Usage:
+ * IPCThreadState::SpGuard guard {
+ * .address = __builtin_frame_address(0),
+ * .context = "...",
+ * };
+ * const auto* orig = pushGetCallingSpGuard(&guard);
+ * {
+ * // will abort if you call getCalling*, unless you are
+ * // serving a nested binder transaction
+ * }
+ * restoreCallingSpGuard(orig);
+ */
+ struct SpGuard {
+ const void* address;
+ const char* context;
+ };
+ const SpGuard* pushGetCallingSpGuard(const SpGuard* guard);
+ void restoreGetCallingSpGuard(const SpGuard* guard);
+ /**
+ * Used internally by getCalling*. Can also be used to assert that
+ * you are in a binder context (getCalling* is valid). This is
+ * intentionally not exposed as a boolean API since code should be
+ * written to know its environment.
+ */
+ void checkContextIsBinderForUse(const char* use) const;
void setStrictModePolicy(int32_t policy);
int32_t getStrictModePolicy() const;
@@ -197,6 +227,7 @@
Parcel mOut;
status_t mLastError;
const void* mServingStackPointer;
+ const SpGuard* mServingStackPointerGuard;
pid_t mCallingPid;
const char* mCallingSid;
uid_t mCallingUid;
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 3dbe2c4..8e46147 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -169,4 +169,17 @@
int32_t* outPid, int32_t* outUid);
bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
+#ifndef __ANDROID__
+// Create an IServiceManager that delegates the service manager on the device via adb.
+// This is can be set as the default service manager at program start, so that
+// defaultServiceManager() returns it:
+// int main() {
+// setDefaultServiceManager(createRpcDelegateServiceManager());
+// auto sm = defaultServiceManager();
+// // ...
+// }
+// Resources are cleaned up when the object is destroyed.
+sp<IServiceManager> createRpcDelegateServiceManager();
+#endif
+
} // namespace android
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 5aaaa0c..02052ad 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -561,6 +561,8 @@
status_t flattenBinder(const sp<IBinder>& binder);
status_t unflattenBinder(sp<IBinder>* out) const;
+ status_t readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const;
+
template<class T>
status_t readAligned(T *pArg) const;
@@ -1315,7 +1317,7 @@
template<typename T>
status_t Parcel::resizeOutVector(std::vector<T>* val) const {
int32_t size;
- status_t err = readInt32(&size);
+ status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
if (err != NO_ERROR) {
return err;
}
@@ -1330,7 +1332,7 @@
template<typename T>
status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
int32_t size;
- status_t err = readInt32(&size);
+ status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
if (err != NO_ERROR) {
return err;
}
@@ -1346,7 +1348,7 @@
template<typename T>
status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
int32_t size;
- status_t err = readInt32(&size);
+ status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
if (err != NO_ERROR) {
return err;
}
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 9e4475c..42c85f9 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -42,6 +42,7 @@
}
mStability = other.mStability;
}
+ ParcelableHolder(ParcelableHolder&& other) = default;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index b9db5d7..72c2ab7 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -18,8 +18,8 @@
#include <binder/IBinder.h>
#include <utils/KeyedVector.h>
-#include <utils/String8.h>
#include <utils/String16.h>
+#include <utils/String8.h>
#include <utils/threads.h>
@@ -30,11 +30,10 @@
class IPCThreadState;
-class ProcessState : public virtual RefBase
-{
+class ProcessState : public virtual RefBase {
public:
- static sp<ProcessState> self();
- static sp<ProcessState> selfOrNull();
+ static sp<ProcessState> self();
+ static sp<ProcessState> selfOrNull();
/* initWithDriver() can be used to configure libbinder to use
* a different binder driver dev node. It must be called *before*
@@ -44,94 +43,101 @@
*
* If this is called with nullptr, the behavior is the same as selfOrNull.
*/
- static sp<ProcessState> initWithDriver(const char *driver);
+ static sp<ProcessState> initWithDriver(const char* driver);
- sp<IBinder> getContextObject(const sp<IBinder>& caller);
+ sp<IBinder> getContextObject(const sp<IBinder>& caller);
- void startThreadPool();
+ void startThreadPool();
- bool becomeContextManager();
+ bool becomeContextManager();
- sp<IBinder> getStrongProxyForHandle(int32_t handle);
- void expungeHandle(int32_t handle, IBinder* binder);
+ sp<IBinder> getStrongProxyForHandle(int32_t handle);
+ void expungeHandle(int32_t handle, IBinder* binder);
- void spawnPooledThread(bool isMain);
-
- status_t setThreadPoolMaxThreadCount(size_t maxThreads);
- status_t enableOnewaySpamDetection(bool enable);
- void giveThreadPoolName();
+ void spawnPooledThread(bool isMain);
- String8 getDriverName();
+ status_t setThreadPoolMaxThreadCount(size_t maxThreads);
+ status_t enableOnewaySpamDetection(bool enable);
+ void giveThreadPoolName();
- ssize_t getKernelReferences(size_t count, uintptr_t* buf);
+ String8 getDriverName();
- // Only usable by the context manager.
- // This refcount includes:
- // 1. Strong references to the node by this and other processes
- // 2. Temporary strong references held by the kernel during a
- // transaction on the node.
- // It does NOT include local strong references to the node
- ssize_t getStrongRefCountForNode(const sp<BpBinder>& binder);
+ ssize_t getKernelReferences(size_t count, uintptr_t* buf);
- enum class CallRestriction {
- // all calls okay
- NONE,
- // log when calls are blocking
- ERROR_IF_NOT_ONEWAY,
- // abort process on blocking calls
- FATAL_IF_NOT_ONEWAY,
- };
- // Sets calling restrictions for all transactions in this process. This must be called
- // before any threads are spawned.
- void setCallRestriction(CallRestriction restriction);
+ // Only usable by the context manager.
+ // This refcount includes:
+ // 1. Strong references to the node by this and other processes
+ // 2. Temporary strong references held by the kernel during a
+ // transaction on the node.
+ // It does NOT include local strong references to the node
+ ssize_t getStrongRefCountForNode(const sp<BpBinder>& binder);
+
+ enum class CallRestriction {
+ // all calls okay
+ NONE,
+ // log when calls are blocking
+ ERROR_IF_NOT_ONEWAY,
+ // abort process on blocking calls
+ FATAL_IF_NOT_ONEWAY,
+ };
+ // Sets calling restrictions for all transactions in this process. This must be called
+ // before any threads are spawned.
+ void setCallRestriction(CallRestriction restriction);
+
+ /**
+ * Get the max number of threads that the kernel can start.
+ *
+ * Note: this is the lower bound. Additional threads may be started.
+ */
+ size_t getThreadPoolMaxThreadCount() const;
private:
- static sp<ProcessState> init(const char *defaultDriver, bool requireDefault);
+ static sp<ProcessState> init(const char* defaultDriver, bool requireDefault);
friend class IPCThreadState;
friend class sp<ProcessState>;
- explicit ProcessState(const char* driver);
- ~ProcessState();
+ explicit ProcessState(const char* driver);
+ ~ProcessState();
- ProcessState(const ProcessState& o);
- ProcessState& operator=(const ProcessState& o);
- String8 makeBinderThreadName();
+ ProcessState(const ProcessState& o);
+ ProcessState& operator=(const ProcessState& o);
+ String8 makeBinderThreadName();
- struct handle_entry {
- IBinder* binder;
- RefBase::weakref_type* refs;
- };
+ struct handle_entry {
+ IBinder* binder;
+ RefBase::weakref_type* refs;
+ };
- handle_entry* lookupHandleLocked(int32_t handle);
+ handle_entry* lookupHandleLocked(int32_t handle);
- String8 mDriverName;
- int mDriverFD;
- void* mVMStart;
+ String8 mDriverName;
+ int mDriverFD;
+ void* mVMStart;
- // Protects thread count and wait variables below.
- pthread_mutex_t mThreadCountLock;
- // Broadcast whenever mWaitingForThreads > 0
- pthread_cond_t mThreadCountDecrement;
- // Number of binder threads current executing a command.
- size_t mExecutingThreadsCount;
- // Number of threads calling IPCThreadState::blockUntilThreadAvailable()
- size_t mWaitingForThreads;
- // Maximum number for binder threads allowed for this process.
- size_t mMaxThreads;
- // Time when thread pool was emptied
- int64_t mStarvationStartTimeMs;
+ // Protects thread count and wait variables below.
+ pthread_mutex_t mThreadCountLock;
+ // Broadcast whenever mWaitingForThreads > 0
+ pthread_cond_t mThreadCountDecrement;
+ // Number of binder threads current executing a command.
+ size_t mExecutingThreadsCount;
+ // Number of threads calling IPCThreadState::blockUntilThreadAvailable()
+ size_t mWaitingForThreads;
+ // Maximum number for binder threads allowed for this process.
+ size_t mMaxThreads;
+ // Time when thread pool was emptied
+ int64_t mStarvationStartTimeMs;
- mutable Mutex mLock; // protects everything below.
+ mutable Mutex mLock; // protects everything below.
- Vector<handle_entry>mHandleToObject;
+ Vector<handle_entry> mHandleToObject;
- bool mThreadPoolStarted;
- volatile int32_t mThreadPoolSeq;
+ bool mThreadPoolStarted;
+ volatile int32_t mThreadPoolSeq;
- CallRestriction mCallRestriction;
+ CallRestriction mCallRestriction;
};
-
+
} // namespace android
// ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/RpcAddress.h b/libs/binder/include/binder/RpcAddress.h
index 5a3f3a6..e428908 100644
--- a/libs/binder/include/binder/RpcAddress.h
+++ b/libs/binder/include/binder/RpcAddress.h
@@ -29,11 +29,7 @@
struct RpcWireAddress;
/**
- * This class represents an identifier of a binder object.
- *
- * The purpose of this class it to hide the ABI of an RpcWireAddress, and
- * potentially allow us to change the size of it in the future (RpcWireAddress
- * is PIMPL, essentially - although the type that is used here is not exposed).
+ * This class represents an identifier across an RPC boundary.
*/
class RpcAddress {
public:
@@ -46,9 +42,20 @@
bool isZero() const;
/**
- * Create a new address which is unique
+ * Create a new random address.
*/
- static RpcAddress unique();
+ static RpcAddress random(bool forServer);
+
+ /**
+ * Whether this address was created with 'bool forServer' true
+ */
+ bool isForServer() const;
+
+ /**
+ * Whether this address is one that could be created with this version of
+ * libbinder.
+ */
+ bool isRecognizedType() const;
/**
* Creates a new address as a copy of an embedded object.
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 8f0c6fd..c8d2857 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -17,6 +17,7 @@
#include <android-base/unique_fd.h>
#include <binder/IBinder.h>
+#include <binder/RpcAddress.h>
#include <binder/RpcSession.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -44,7 +45,7 @@
* }
* server->join();
*/
-class RpcServer final : public virtual RefBase {
+class RpcServer final : public virtual RefBase, private RpcSession::EventListener {
public:
static sp<RpcServer> make();
@@ -97,7 +98,7 @@
*
* If this is not specified, this will be a single-threaded server.
*
- * TODO(b/185167543): these are currently created per client, but these
+ * TODO(b/167966510): these are currently created per client, but these
* should be shared.
*/
void setMaxThreads(size_t threads);
@@ -117,17 +118,31 @@
sp<IBinder> getRootObject();
/**
+ * Runs join() in a background thread. Immediately returns.
+ */
+ void start();
+
+ /**
* You must have at least one client session before calling this.
*
- * TODO(b/185167543): way to shut down?
+ * If a client needs to actively terminate join, call shutdown() in a separate thread.
+ *
+ * At any given point, there can only be one thread calling join().
+ *
+ * Warning: if shutdown is called, this will return while the shutdown is
+ * still occurring. To ensure that the service is fully shutdown, you might
+ * want to call shutdown after 'join' returns.
*/
void join();
/**
- * Accept one connection on this server. You must have at least one client
- * session before calling this.
+ * Shut down any existing join(). Return true if successfully shut down, false otherwise
+ * (e.g. no join() is running). Will wait for the server to be fully
+ * shutdown.
+ *
+ * Warning: this will hang if it is called from its own thread.
*/
- [[nodiscard]] bool acceptOne();
+ [[nodiscard]] bool shutdown();
/**
* For debugging!
@@ -137,28 +152,29 @@
~RpcServer();
- // internal use only
-
- void onSessionTerminating(const sp<RpcSession>& session);
-
private:
friend sp<RpcServer>;
RpcServer();
- void establishConnection(sp<RpcServer>&& session, base::unique_fd clientFd);
+ void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+ void onSessionIncomingThreadEnded() override;
+
+ static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd);
bool setupSocketServer(const RpcSocketAddress& address);
bool mAgreedExperimental = false;
- bool mStarted = false; // TODO(b/185167543): support dynamically added clients
size_t mMaxThreads = 1;
base::unique_fd mServer; // socket we are accepting sessions on
std::mutex mLock; // for below
+ std::unique_ptr<std::thread> mJoinThread;
+ bool mJoinThreadRunning = false;
std::map<std::thread::id, std::thread> mConnectingThreads;
sp<IBinder> mRootObject;
wp<IBinder> mRootObjectWeak;
- std::map<int32_t, sp<RpcSession>> mSessions;
- int32_t mSessionIdCounter = 0;
+ std::map<RpcAddress, sp<RpcSession>> mSessions;
+ std::unique_ptr<RpcSession::FdTrigger> mShutdownTrigger;
+ std::condition_variable mShutdownCv;
};
} // namespace android
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index bcc213c..fdca2a9 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -47,6 +47,19 @@
static sp<RpcSession> make();
/**
+ * Set the maximum number of threads allowed to be made (for things like callbacks).
+ * By default, this is 0. This must be called before setting up this connection as a client.
+ * Server sessions will inherits this value from RpcServer.
+ *
+ * If this is called, 'shutdown' on this session must also be called.
+ * Otherwise, a threadpool will leak.
+ *
+ * TODO(b/189955605): start these dynamically
+ */
+ void setMaxThreads(size_t threads);
+ size_t getMaxThreads();
+
+ /**
* This should be called once per thread, matching 'join' in the remote
* process.
*/
@@ -83,42 +96,101 @@
*/
status_t getRemoteMaxThreads(size_t* maxThreads);
- [[nodiscard]] status_t transact(const RpcAddress& address, uint32_t code, const Parcel& data,
+ /**
+ * Shuts down the service.
+ *
+ * For client sessions, wait can be true or false. For server sessions,
+ * waiting is not currently supported (will abort).
+ *
+ * Warning: this is currently not active/nice (the server isn't told we're
+ * shutting down). Being nicer to the server could potentially make it
+ * reclaim resources faster.
+ *
+ * If this is called w/ 'wait' true, then this will wait for shutdown to
+ * complete before returning. This will hang if it is called from the
+ * session threadpool (when processing received calls).
+ */
+ [[nodiscard]] bool shutdownAndWait(bool wait);
+
+ [[nodiscard]] status_t transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
[[nodiscard]] status_t sendDecStrong(const RpcAddress& address);
~RpcSession();
- wp<RpcServer> server();
+ /**
+ * Server if this session is created as part of a server (symmetrical to
+ * client servers). Otherwise, nullptr.
+ */
+ sp<RpcServer> server();
// internal only
const std::unique_ptr<RpcState>& state() { return mState; }
- class PrivateAccessorForId {
- private:
- friend class RpcSession;
- friend class RpcState;
- explicit PrivateAccessorForId(const RpcSession* session) : mSession(session) {}
-
- const std::optional<int32_t> get() { return mSession->mId; }
-
- const RpcSession* mSession;
- };
- PrivateAccessorForId getPrivateAccessorForId() const { return PrivateAccessorForId(this); }
-
private:
- friend PrivateAccessorForId;
friend sp<RpcSession>;
friend RpcServer;
+ friend RpcState;
RpcSession();
- status_t readId();
+ /** This is not a pipe. */
+ struct FdTrigger {
+ /** Returns nullptr for error case */
+ static std::unique_ptr<FdTrigger> make();
- // transfer ownership of thread
- void preJoin(std::thread thread);
- // join on thread passed to preJoin
- void join(base::unique_fd client);
- void terminateLocked();
+ /**
+ * Close the write end of the pipe so that the read end receives POLLHUP.
+ * Not threadsafe.
+ */
+ void trigger();
+
+ /**
+ * Whether this has been triggered.
+ */
+ bool isTriggered();
+
+ /**
+ * Poll for a read event.
+ *
+ * event - for pollfd
+ *
+ * Return:
+ * true - time to read!
+ * false - trigger happened
+ */
+ status_t triggerablePoll(base::borrowed_fd fd, int16_t event);
+
+ /**
+ * Read (or write), but allow to be interrupted by this trigger.
+ *
+ * Return:
+ * true - succeeded in completely processing 'size'
+ * false - interrupted (failure or trigger)
+ */
+ status_t interruptableReadFully(base::borrowed_fd fd, void* data, size_t size);
+ status_t interruptableWriteFully(base::borrowed_fd fd, const void* data, size_t size);
+
+ private:
+ base::unique_fd mWrite;
+ base::unique_fd mRead;
+ };
+
+ class EventListener : public virtual RefBase {
+ public:
+ virtual void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0;
+ virtual void onSessionIncomingThreadEnded() = 0;
+ };
+
+ class WaitForShutdownListener : public EventListener {
+ public:
+ void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+ void onSessionIncomingThreadEnded() override;
+ void waitForShutdown(std::unique_lock<std::mutex>& lock);
+
+ private:
+ std::condition_variable mCv;
+ bool mShutdown = false;
+ };
struct RpcConnection : public RefBase {
base::unique_fd fd;
@@ -126,14 +198,41 @@
// whether this or another thread is currently using this fd to make
// or receive transactions.
std::optional<pid_t> exclusiveTid;
+
+ bool allowNested = false;
};
- bool setupSocketClient(const RpcSocketAddress& address);
- bool setupOneSocketClient(const RpcSocketAddress& address, int32_t sessionId);
- void addClientConnection(base::unique_fd fd);
- void setForServer(const wp<RpcServer>& server, int32_t sessionId);
- sp<RpcConnection> assignServerToThisThread(base::unique_fd fd);
- bool removeServerConnection(const sp<RpcConnection>& connection);
+ status_t readId();
+
+ // A thread joining a server must always call these functions in order, and
+ // cleanup is only programmed once into join. These are in separate
+ // functions in order to allow for different locks to be taken during
+ // different parts of setup.
+ //
+ // transfer ownership of thread (usually done while a lock is taken on the
+ // structure which originally owns the thread)
+ void preJoinThreadOwnership(std::thread thread);
+ // pass FD to thread and read initial connection information
+ struct PreJoinSetupResult {
+ // Server connection object associated with this
+ sp<RpcConnection> connection;
+ // Status of setup
+ status_t status;
+ };
+ PreJoinSetupResult preJoinSetup(base::unique_fd fd);
+ // join on thread passed to preJoinThreadOwnership
+ static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result);
+
+ [[nodiscard]] bool setupSocketClient(const RpcSocketAddress& address);
+ [[nodiscard]] bool setupOneSocketConnection(const RpcSocketAddress& address,
+ const RpcAddress& sessionId, bool server);
+ [[nodiscard]] bool addIncomingConnection(base::unique_fd fd);
+ [[nodiscard]] bool addOutgoingConnection(base::unique_fd fd, bool init);
+ [[nodiscard]] bool setForServer(const wp<RpcServer>& server,
+ const wp<RpcSession::EventListener>& eventListener,
+ const RpcAddress& sessionId);
+ sp<RpcConnection> assignIncomingConnectionToThisThread(base::unique_fd fd);
+ [[nodiscard]] bool removeIncomingConnection(const sp<RpcConnection>& connection);
enum class ConnectionUse {
CLIENT,
@@ -141,12 +240,14 @@
CLIENT_REFCOUNT,
};
- // RAII object for session connection
+ // Object representing exclusive access to a connection.
class ExclusiveConnection {
public:
- explicit ExclusiveConnection(const sp<RpcSession>& session, ConnectionUse use);
+ static status_t find(const sp<RpcSession>& session, ConnectionUse use,
+ ExclusiveConnection* connection);
+
~ExclusiveConnection();
- const base::unique_fd& fd() { return mConnection->fd; }
+ const sp<RpcConnection>& get() { return mConnection; }
private:
static void findConnection(pid_t tid, sp<RpcConnection>* exclusive,
@@ -163,13 +264,13 @@
bool mReentrant = false;
};
- // On the other side of a session, for each of mClientConnections here, there should
- // be one of mServerConnections on the other side (and vice versa).
+ // On the other side of a session, for each of mOutgoingConnections here, there should
+ // be one of mIncomingConnections on the other side (and vice versa).
//
// For the simplest session, a single server with one client, you would
// have:
- // - the server has a single 'mServerConnections' and a thread listening on this
- // - the client has a single 'mClientConnections' and makes calls to this
+ // - the server has a single 'mIncomingConnections' and a thread listening on this
+ // - the client has a single 'mOutgoingConnections' and makes calls to this
// - here, when the client makes a call, the server can call back into it
// (nested calls), but outside of this, the client will only ever read
// calls from the server when it makes a call itself.
@@ -178,27 +279,26 @@
// serve calls to the server at all times (e.g. if it hosts a callback)
wp<RpcServer> mForServer; // maybe null, for client sessions
+ sp<WaitForShutdownListener> mShutdownListener; // used for client sessions
+ wp<EventListener> mEventListener; // mForServer if server, mShutdownListener if client
- // TODO(b/183988761): this shouldn't be guessable
- std::optional<int32_t> mId;
+ std::optional<RpcAddress> mId;
+
+ std::unique_ptr<FdTrigger> mShutdownTrigger;
std::unique_ptr<RpcState> mState;
std::mutex mMutex; // for all below
+ size_t mMaxThreads = 0;
+
std::condition_variable mAvailableConnectionCv; // for mWaitingThreads
size_t mWaitingThreads = 0;
// hint index into clients, ++ when sending an async transaction
- size_t mClientConnectionsOffset = 0;
- std::vector<sp<RpcConnection>> mClientConnections;
- std::vector<sp<RpcConnection>> mServerConnections;
-
- // TODO(b/185167543): use for reverse sessions (allow client to also
- // serve calls on a session).
- // TODO(b/185167543): allow sharing between different sessions in a
- // process? (or combine with mServerConnections)
+ size_t mOutgoingConnectionsOffset = 0;
+ std::vector<sp<RpcConnection>> mOutgoingConnections;
+ std::vector<sp<RpcConnection>> mIncomingConnections;
std::map<std::thread::id, std::thread> mThreads;
- bool mTerminated = false;
};
} // namespace android
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index f4bfac8..629b565 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -100,7 +100,7 @@
static void markVintf(IBinder* binder);
// WARNING: for debugging only
- static void debugLogStability(const std::string& tag, const sp<IBinder>& binder);
+ static std::string debugToString(const sp<IBinder>& binder);
// WARNING: This is only ever expected to be called by auto-generated code or tests.
// You likely want to change or modify the stability of the interface you are using.
@@ -136,14 +136,15 @@
VINTF = 0b111111,
};
- // This is the format of stability passed on the wire.
+ // This is the format of stability passed on the wire. It is only 2 bytes
+ // long, but 2 bytes in addition to this are reserved here. The difference
+ // in size is in order to free up space in BBinder, which is fixed by
+ // prebuilts inheriting from it.
struct Category {
- static inline Category fromRepr(int32_t representation) {
+ static inline Category fromRepr(int16_t representation) {
return *reinterpret_cast<Category*>(&representation);
}
- int32_t repr() const {
- return *reinterpret_cast<const int32_t*>(this);
- }
+ int16_t repr() const { return *reinterpret_cast<const int16_t*>(this); }
static inline Category currentFromLevel(Level level);
bool operator== (const Category& o) const {
@@ -161,12 +162,10 @@
// class must write parcels according to the version documented here.
uint8_t version;
- uint8_t reserved[2];
-
// bitmask of Stability::Level
Level level;
};
- static_assert(sizeof(Category) == sizeof(int32_t));
+ static_assert(sizeof(Category) == sizeof(int16_t));
// returns the stability according to how this was built
static Level getLocalLevel();
diff --git a/libs/binder/libbinder.arm32.map b/libs/binder/libbinder.arm32.map
deleted file mode 100644
index f26c33d..0000000
--- a/libs/binder/libbinder.arm32.map
+++ /dev/null
@@ -1,1393 +0,0 @@
-LIBBINDER {
- global:
- getBinderKernelReferences;
- kDefaultDriver;
- _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
- _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
- _ZN7android10AllocationD0Ev;
- _ZN7android10AllocationD1Ev;
- _ZN7android10AllocationD2Ev;
- _ZN7android10IInterface8asBinderEPKS0_;
- _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
- _ZN7android10IInterfaceC2Ev;
- _ZN7android10IInterfaceD0Ev;
- _ZN7android10IInterfaceD1Ev;
- _ZN7android10IInterfaceD2Ev;
- _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij;
- _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEEij;
- _ZN7android10MemoryBaseD0Ev;
- _ZN7android10MemoryBaseD1Ev;
- _ZN7android10MemoryBaseD2Ev;
- _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
- _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
- _ZN7android10RpcAddress4zeroEv;
- _ZN7android10RpcAddress6uniqueEv;
- _ZN7android10RpcAddressC1Ev;
- _ZN7android10RpcAddressC2Ev;
- _ZN7android10RpcAddressD1Ev;
- _ZN7android10RpcAddressD2Ev;
- _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
- _ZN7android10RpcSession13getRootObjectEv;
- _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
- _ZN7android10RpcSession15setupInetClientEPKcj;
- _ZN7android10RpcSession15terminateLockedEv;
- _ZN7android10RpcSession16setupVsockClientEjj;
- _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
- _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEj;
- _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
- _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
- _ZN7android10RpcSession19getRemoteMaxThreadsEPj;
- _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
- _ZN7android10RpcSession21setupUnixDomainClientEPKc;
- _ZN7android10RpcSession22addNullDebuggingClientEv;
- _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
- _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4makeEv;
- _ZN7android10RpcSession6readIdEv;
- _ZN7android10RpcSession6serverEv;
- _ZN7android10RpcSession7preJoinENSt3__16threadE;
- _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
- _ZN7android10RpcSessionC1Ev;
- _ZN7android10RpcSessionC2Ev;
- _ZN7android10RpcSessionD0Ev;
- _ZN7android10RpcSessionD1Ev;
- _ZN7android10RpcSessionD2Ev;
- _ZN7android10TextOutputC2Ev;
- _ZN7android10TextOutputD0Ev;
- _ZN7android10TextOutputD1Ev;
- _ZN7android10TextOutputD2Ev;
- _ZN7android10zeroMemoryEPhj;
- _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_21IPermissionControllerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
- _ZN7android11IMemoryHeap10descriptorE;
- _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android11IMemoryHeap12default_implE;
- _ZN7android11IMemoryHeap14getDefaultImplEv;
- _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android11IMemoryHeapC2Ev;
- _ZN7android11IMemoryHeapD0Ev;
- _ZN7android11IMemoryHeapD1Ev;
- _ZN7android11IMemoryHeapD2Ev;
- _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android12BnMemoryHeapC2Ev;
- _ZN7android12BnMemoryHeapD0Ev;
- _ZN7android12BnMemoryHeapD1Ev;
- _ZN7android12BnMemoryHeapD2Ev;
- _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapD0Ev;
- _ZN7android12BpMemoryHeapD1Ev;
- _ZN7android12BpMemoryHeapD2Ev;
- _ZN7android12gTextBuffersE;
- _ZN7android12MemoryDealer10deallocateEj;
- _ZN7android12MemoryDealer22getAllocationAlignmentEv;
- _ZN7android12MemoryDealer8allocateEj;
- _ZN7android12MemoryDealerC1EjPKcj;
- _ZN7android12MemoryDealerC2EjPKcj;
- _ZN7android12MemoryDealerD0Ev;
- _ZN7android12MemoryDealerD1Ev;
- _ZN7android12MemoryDealerD2Ev;
- _ZN7android12printHexDataEiPKvjjijbPFvPvPKcES2_;
- _ZN7android12ProcessState10selfOrNullEv;
- _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
- _ZN7android12ProcessState13getDriverNameEv;
- _ZN7android12ProcessState14initWithDriverEPKc;
- _ZN7android12ProcessState15startThreadPoolEv;
- _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android12ProcessState17spawnPooledThreadEb;
- _ZN7android12ProcessState18giveThreadPoolNameEv;
- _ZN7android12ProcessState18lookupHandleLockedEi;
- _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
- _ZN7android12ProcessState19getKernelReferencesEjPj;
- _ZN7android12ProcessState20becomeContextManagerEv;
- _ZN7android12ProcessState20makeBinderThreadNameEv;
- _ZN7android12ProcessState23getStrongProxyForHandleEi;
- _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
- _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
- _ZN7android12ProcessState27setThreadPoolMaxThreadCountEj;
- _ZN7android12ProcessState4initEPKcb;
- _ZN7android12ProcessState4selfEv;
- _ZN7android12ProcessStateC1EPKc;
- _ZN7android12ProcessStateC2EPKc;
- _ZN7android12ProcessStateD0Ev;
- _ZN7android12ProcessStateD1Ev;
- _ZN7android12ProcessStateD2Ev;
- _ZN7android13printTypeCodeEjPFvPvPKcES0_;
- _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhjPKyj;
- _ZN7android14IPCThreadState10selfOrNullEv;
- _ZN7android14IPCThreadState11clearCallerEv;
- _ZN7android14IPCThreadState11stopProcessEb;
- _ZN7android14IPCThreadState12setupPollingEPi;
- _ZN7android14IPCThreadState13decWeakHandleEi;
- _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
- _ZN7android14IPCThreadState13flushCommandsEv;
- _ZN7android14IPCThreadState13flushIfNeededEv;
- _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState14clearLastErrorEv;
- _ZN7android14IPCThreadState14executeCommandEi;
- _ZN7android14IPCThreadState14joinThreadPoolEb;
- _ZN7android14IPCThreadState14talkWithDriverEb;
- _ZN7android14IPCThreadState15decStrongHandleEi;
- _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
- _ZN7android14IPCThreadState16threadDestructorEPv;
- _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
- _ZN7android14IPCThreadState19setStrictModePolicyEi;
- _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
- _ZN7android14IPCThreadState20clearCallingIdentityEv;
- _ZN7android14IPCThreadState20getAndExecuteCommandEv;
- _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
- _ZN7android14IPCThreadState20handlePolledCommandsEv;
- _ZN7android14IPCThreadState20processPendingDerefsEv;
- _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
- _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
- _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
- _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState22processPostWriteDerefsEv;
- _ZN7android14IPCThreadState22restoreCallingIdentityEx;
- _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
- _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
- _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState24restoreCallingWorkSourceEx;
- _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
- _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
- _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
- _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
- _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
- _ZN7android14IPCThreadState4selfEv;
- _ZN7android14IPCThreadState6freezeEibj;
- _ZN7android14IPCThreadState7processEv;
- _ZN7android14IPCThreadState8shutdownEv;
- _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
- _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
- _ZN7android14IPCThreadStateC1Ev;
- _ZN7android14IPCThreadStateC2Ev;
- _ZN7android14IPCThreadStateD1Ev;
- _ZN7android14IPCThreadStateD2Ev;
- _ZN7android14IShellCallback10descriptorE;
- _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android14IShellCallback12default_implE;
- _ZN7android14IShellCallback14getDefaultImplEv;
- _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android14IShellCallbackC2Ev;
- _ZN7android14IShellCallbackD0Ev;
- _ZN7android14IShellCallbackD1Ev;
- _ZN7android14IShellCallbackD2Ev;
- _ZN7android14MemoryHeapBase4initEiPvjiPKc;
- _ZN7android14MemoryHeapBase5mapfdEibjl;
- _ZN7android14MemoryHeapBase7disposeEv;
- _ZN7android14MemoryHeapBaseC1Eijjl;
- _ZN7android14MemoryHeapBaseC1EjjPKc;
- _ZN7android14MemoryHeapBaseC1EPKcjj;
- _ZN7android14MemoryHeapBaseC1Ev;
- _ZN7android14MemoryHeapBaseC2Eijjl;
- _ZN7android14MemoryHeapBaseC2EjjPKc;
- _ZN7android14MemoryHeapBaseC2EPKcjj;
- _ZN7android14MemoryHeapBaseC2Ev;
- _ZN7android14MemoryHeapBaseD0Ev;
- _ZN7android14MemoryHeapBaseD1Ev;
- _ZN7android14MemoryHeapBaseD2Ev;
- _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android15checkPermissionERKNS_8String16Eij;
- _ZN7android15IResultReceiver10descriptorE;
- _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android15IResultReceiver12default_implE;
- _ZN7android15IResultReceiver14getDefaultImplEv;
- _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android15IResultReceiverC2Ev;
- _ZN7android15IResultReceiverD0Ev;
- _ZN7android15IResultReceiverD1Ev;
- _ZN7android15IResultReceiverD2Ev;
- _ZN7android15IServiceManagerC2Ev;
- _ZN7android15IServiceManagerD0Ev;
- _ZN7android15IServiceManagerD1Ev;
- _ZN7android15IServiceManagerD2Ev;
- _ZN7android15PermissionCache10purgeCacheEv;
- _ZN7android15PermissionCache15checkPermissionERKNS_8String16Eij;
- _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16E;
- _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16EPiS4_;
- _ZN7android15PermissionCache5cacheERKNS_8String16Ejb;
- _ZN7android15PermissionCache5purgeEv;
- _ZN7android15PermissionCacheC1Ev;
- _ZN7android15PermissionCacheC2Ev;
- _ZN7android15stringForIndentEi;
- _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android18BufferedTextOutput10moveIndentEi;
- _ZN7android18BufferedTextOutput10pushBundleEv;
- _ZN7android18BufferedTextOutput5printEPKcj;
- _ZN7android18BufferedTextOutput9popBundleEv;
- _ZN7android18BufferedTextOutputC2Ej;
- _ZN7android18BufferedTextOutputD0Ev;
- _ZN7android18BufferedTextOutputD1Ev;
- _ZN7android18BufferedTextOutputD2Ev;
- _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
- _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
- _ZN7android18ServiceManagerShim12listServicesEi;
- _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
- _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
- _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
- _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18the_context_objectE;
- _ZN7android20PermissionController10getServiceEv;
- _ZN7android20PermissionController13getPackageUidERKNS_8String16Ei;
- _ZN7android20PermissionController15checkPermissionERKNS_8String16Eii;
- _ZN7android20PermissionController17getPackagesForUidEjRNS_6VectorINS_8String16EEE;
- _ZN7android20PermissionController19isRuntimePermissionERKNS_8String16E;
- _ZN7android20PermissionController6noteOpERKNS_8String16EiS3_;
- _ZN7android20PermissionControllerC1Ev;
- _ZN7android20PermissionControllerC2Ev;
- _ZN7android21defaultServiceManagerEv;
- _ZN7android21IPermissionController10descriptorE;
- _ZN7android21IPermissionController11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android21IPermissionController12default_implE;
- _ZN7android21IPermissionController14getDefaultImplEv;
- _ZN7android21IPermissionController14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android21IPermissionControllerC2Ev;
- _ZN7android21IPermissionControllerD0Ev;
- _ZN7android21IPermissionControllerD1Ev;
- _ZN7android21IPermissionControllerD2Ev;
- _ZN7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android22checkCallingPermissionERKNS_8String16E;
- _ZN7android22checkCallingPermissionERKNS_8String16EPiS3_;
- _ZN7android22SimpleBestFitAllocator10deallocateEj;
- _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
- _ZN7android22SimpleBestFitAllocator5allocEjj;
- _ZN7android22SimpleBestFitAllocator7deallocEj;
- _ZN7android22SimpleBestFitAllocator8allocateEjj;
- _ZN7android22SimpleBestFitAllocatorC1Ej;
- _ZN7android22SimpleBestFitAllocatorC2Ej;
- _ZN7android22SimpleBestFitAllocatorD1Ev;
- _ZN7android22SimpleBestFitAllocatorD2Ev;
- _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
- _ZN7android2os15IClientCallback10descriptorE;
- _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IClientCallback12default_implE;
- _ZN7android2os15IClientCallback14getDefaultImplEv;
- _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IClientCallbackC2Ev;
- _ZN7android2os15IClientCallbackD0Ev;
- _ZN7android2os15IClientCallbackD1Ev;
- _ZN7android2os15IClientCallbackD2Ev;
- _ZN7android2os15IServiceManager10descriptorE;
- _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IServiceManager12default_implE;
- _ZN7android2os15IServiceManager14getDefaultImplEv;
- _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IServiceManagerC2Ev;
- _ZN7android2os15IServiceManagerD0Ev;
- _ZN7android2os15IServiceManagerD1Ev;
- _ZN7android2os15IServiceManagerD2Ev;
- _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnClientCallbackC2Ev;
- _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnServiceManagerC2Ev;
- _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
- _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
- _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
- _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
- _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
- _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
- _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
- _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
- _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback10descriptorE;
- _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback12default_implE;
- _ZN7android2os16IServiceCallback14getDefaultImplEv;
- _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os16IServiceCallbackC2Ev;
- _ZN7android2os16IServiceCallbackD0Ev;
- _ZN7android2os16IServiceCallbackD1Ev;
- _ZN7android2os16IServiceCallbackD2Ev;
- _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os17BnServiceCallbackC2Ev;
- _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
- _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIxNS5_9allocatorIxEEEE;
- _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEj;
- _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
- _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
- _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
- _ZN7android2os17PersistableBundle7putLongERKNS_8String16Ex;
- _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
- _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
- _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC1Ev;
- _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC2Ev;
- _ZN7android2os20ParcelFileDescriptorD0Ev;
- _ZN7android2os20ParcelFileDescriptorD1Ev;
- _ZN7android2os20ParcelFileDescriptorD2Ev;
- _ZN7android4aerrE;
- _ZN7android4alogE;
- _ZN7android4aoutE;
- _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
- _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
- _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
- _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
- _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
- _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder20LazyServiceRegistrarC1Ev;
- _ZN7android6binder20LazyServiceRegistrarC2Ev;
- _ZN7android6binder6Status11fromStatusTEi;
- _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
- _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
- _ZN7android6binder6Status14setFromStatusTEi;
- _ZN7android6binder6Status17exceptionToStringEi;
- _ZN7android6binder6Status17fromExceptionCodeEi;
- _ZN7android6binder6Status17fromExceptionCodeEiPKc;
- _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
- _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status24fromServiceSpecificErrorEi;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status2okEv;
- _ZN7android6binder6StatusC1Eii;
- _ZN7android6binder6StatusC1EiiRKNS_7String8E;
- _ZN7android6binder6StatusC2Eii;
- _ZN7android6binder6StatusC2EiiRKNS_7String8E;
- _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
- _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
- _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
- _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
- _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
- _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
- _ZN7android6Parcel10appendFromEPKS0_jj;
- _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
- _ZN7android6Parcel10writeFloatEf;
- _ZN7android6Parcel10writeInt32Ei;
- _ZN7android6Parcel10writeInt64Ex;
- _ZN7android6Parcel11compareDataERKS0_;
- _ZN7android6Parcel11finishWriteEj;
- _ZN7android6Parcel11setDataSizeEj;
- _ZN7android6Parcel11writeDoubleEd;
- _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
- _ZN7android6Parcel11writeUint32Ej;
- _ZN7android6Parcel11writeUint64Ey;
- _ZN7android6Parcel12pushAllowFdsEb;
- _ZN7android6Parcel12restartWriteEj;
- _ZN7android6Parcel12writeCStringEPKc;
- _ZN7android6Parcel12writeInplaceEj;
- _ZN7android6Parcel12writePointerEj;
- _ZN7android6Parcel12writeString8EPKcj;
- _ZN7android6Parcel12writeString8ERKNS_7String8E;
- _ZN7android6Parcel13continueWriteEj;
- _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13writeString16EPKDsj;
- _ZN7android6Parcel13writeString16ERKNS_8String16E;
- _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
- _ZN7android6Parcel13writeUnpaddedEPKvj;
- _ZN7android6Parcel14acquireObjectsEv;
- _ZN7android6Parcel14freeDataNoInitEv;
- _ZN7android6Parcel14releaseObjectsEv;
- _ZN7android6Parcel14writeByteArrayEjPKh;
- _ZN7android6Parcel15restoreAllowFdsEb;
- _ZN7android6Parcel15setDataCapacityEj;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZN7android6Parcel15writeInt32ArrayEjPKi;
- _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIxNS1_9allocatorIxEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
- _ZN7android6Parcel16writeNoExceptionEv;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
- _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorIyNS1_9allocatorIyEEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
- _ZN7android6Parcel18getGlobalAllocSizeEv;
- _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel19getGlobalAllocCountEv;
- _ZN7android6Parcel19ipcSetDataReferenceEPKhjPKyjPFvPS0_S2_jS4_jE;
- _ZN7android6Parcel19writeFileDescriptorEib;
- _ZN7android6Parcel19writeInterfaceTokenEPKDsj;
- _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
- _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZN7android6Parcel20closeFileDescriptorsEv;
- _ZN7android6Parcel22writeDupFileDescriptorEi;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZN7android6Parcel25writeParcelFileDescriptorEib;
- _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
- _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
- _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
- _ZN7android6Parcel4Blob4initEiPvjb;
- _ZN7android6Parcel4Blob5clearEv;
- _ZN7android6Parcel4Blob7releaseEv;
- _ZN7android6Parcel4BlobC1Ev;
- _ZN7android6Parcel4BlobC2Ev;
- _ZN7android6Parcel4BlobD1Ev;
- _ZN7android6Parcel4BlobD2Ev;
- _ZN7android6Parcel5writeEPKvj;
- _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
- _ZN7android6Parcel7setDataEPKhj;
- _ZN7android6Parcel8freeDataEv;
- _ZN7android6Parcel8growDataEj;
- _ZN7android6Parcel8setErrorEi;
- _ZN7android6Parcel9initStateEv;
- _ZN7android6Parcel9writeBlobEjbPNS0_12WritableBlobE;
- _ZN7android6Parcel9writeBoolEb;
- _ZN7android6Parcel9writeByteEa;
- _ZN7android6Parcel9writeCharEDs;
- _ZN7android6ParcelC1Ev;
- _ZN7android6ParcelC2Ev;
- _ZN7android6ParcelD1Ev;
- _ZN7android6ParcelD2Ev;
- _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinder10pingBinderEv;
- _ZN7android7BBinder11getDebugPidEv;
- _ZN7android7BBinder11isInheritRtEv;
- _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android7BBinder11localBinderEv;
- _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android7BBinder12detachObjectEPKv;
- _ZN7android7BBinder12getExtensionEv;
- _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
- _ZN7android7BBinder12setInheritRtEb;
- _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android7BBinder15isRequestingSidEv;
- _ZN7android7BBinder16setRequestingSidEb;
- _ZN7android7BBinder17getOrCreateExtrasEv;
- _ZN7android7BBinder21getMinSchedulerPolicyEv;
- _ZN7android7BBinder21setMinSchedulerPolicyEii;
- _ZN7android7BBinder23getMinSchedulerPriorityEv;
- _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinderC1Ev;
- _ZN7android7BBinderC2Ev;
- _ZN7android7BBinderD0Ev;
- _ZN7android7BBinderD1Ev;
- _ZN7android7BBinderD2Ev;
- _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
- _ZN7android7content2pm21IPackageManagerNative10descriptorE;
- _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm21IPackageManagerNative12default_implE;
- _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
- _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm21IPackageManagerNativeC2Ev;
- _ZN7android7content2pm21IPackageManagerNativeD0Ev;
- _ZN7android7content2pm21IPackageManagerNativeD1Ev;
- _ZN7android7content2pm21IPackageManagerNativeD2Ev;
- _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
- _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
- _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
- _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
- _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPx;
- _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
- _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
- _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
- _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver12default_implE;
- _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
- _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm22IPackageChangeObserverC2Ev;
- _ZN7android7content2pm22IPackageChangeObserverD0Ev;
- _ZN7android7content2pm22IPackageChangeObserverD1Ev;
- _ZN7android7content2pm22IPackageChangeObserverD2Ev;
- _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
- _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
- _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7HexDumpC1EPKvjj;
- _ZN7android7HexDumpC2EPKvjj;
- _ZN7android7IBinder11getDebugPidEPi;
- _ZN7android7IBinder11localBinderEv;
- _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
- _ZN7android7IBinder12remoteBinderEv;
- _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
- _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
- _ZN7android7IBinderC2Ev;
- _ZN7android7IBinderD0Ev;
- _ZN7android7IBinderD1Ev;
- _ZN7android7IBinderD2Ev;
- _ZN7android7IMemory10descriptorE;
- _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7IMemory12default_implE;
- _ZN7android7IMemory14getDefaultImplEv;
- _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android7IMemoryC2Ev;
- _ZN7android7IMemoryD0Ev;
- _ZN7android7IMemoryD1Ev;
- _ZN7android7IMemoryD2Ev;
- _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BnMemoryC2Ev;
- _ZN7android8BnMemoryD0Ev;
- _ZN7android8BnMemoryD1Ev;
- _ZN7android8BnMemoryD2Ev;
- _ZN7android8BpBinder10onFirstRefEv;
- _ZN7android8BpBinder10pingBinderEv;
- _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android8BpBinder12detachObjectEPKv;
- _ZN7android8BpBinder12remoteBinderEv;
- _ZN7android8BpBinder12sendObituaryEv;
- _ZN7android8BpBinder12sTrackingMapE;
- _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
- _ZN7android8BpBinder13ObjectManager4killEv;
- _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
- _ZN7android8BpBinder13ObjectManager6detachEPKv;
- _ZN7android8BpBinder13ObjectManagerC1Ev;
- _ZN7android8BpBinder13ObjectManagerC2Ev;
- _ZN7android8BpBinder13ObjectManagerD1Ev;
- _ZN7android8BpBinder13ObjectManagerD2Ev;
- _ZN7android8BpBinder13sTrackingLockE;
- _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
- _ZN7android8BpBinder14sLimitCallbackE;
- _ZN7android8BpBinder15onLastStrongRefEPKv;
- _ZN7android8BpBinder15sNumTrackedUidsE;
- _ZN7android8BpBinder16enableCountByUidEv;
- _ZN7android8BpBinder16setLimitCallbackEPFviE;
- _ZN7android8BpBinder17disableCountByUidEv;
- _ZN7android8BpBinder18sCountByUidEnabledE;
- _ZN7android8BpBinder19getBinderProxyCountEj;
- _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZN7android8BpBinder20setCountByUidEnabledEb;
- _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
- _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
- _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
- _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
- _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android8BpBinder6createEi;
- _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC1EONS0_9RpcHandleE;
- _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC2EONS0_9RpcHandleE;
- _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderD0Ev;
- _ZN7android8BpBinderD1Ev;
- _ZN7android8BpBinderD2Ev;
- _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryD0Ev;
- _ZN7android8BpMemoryD1Ev;
- _ZN7android8BpMemoryD2Ev;
- _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
- _ZN7android8internal9Stability11levelStringENS1_5LevelE;
- _ZN7android8internal9Stability13getLocalLevelEv;
- _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
- _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
- _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
- _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
- _ZN7android8internal9Stability8Category11debugStringEv;
- _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
- _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
- _ZN7android8RpcState11CommandDataC1Ej;
- _ZN7android8RpcState11CommandDataC2Ej;
- _ZN7android8RpcState12countBindersEv;
- _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
- _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
- _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPj;
- _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
- _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
- _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
- _ZN7android8RpcState4dumpEv;
- _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvj;
- _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvj;
- _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
- _ZN7android8RpcState9terminateEv;
- _ZN7android8RpcStateC1Ev;
- _ZN7android8RpcStateC2Ev;
- _ZN7android8RpcStateD1Ev;
- _ZN7android8RpcStateD2Ev;
- _ZN7android9BpRefBase10onFirstRefEv;
- _ZN7android9BpRefBase15onLastStrongRefEPKv;
- _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseD0Ev;
- _ZN7android9BpRefBaseD1Ev;
- _ZN7android9BpRefBaseD2Ev;
- _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCache10dump_heapsEv;
- _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCacheC1Ev;
- _ZN7android9HeapCacheC2Ev;
- _ZN7android9HeapCacheD0Ev;
- _ZN7android9HeapCacheD1Ev;
- _ZN7android9HeapCacheD2Ev;
- _ZN7android9hexStringEPKvj;
- _ZN7android9RpcServer12listSessionsEv;
- _ZN7android9RpcServer13getMaxThreadsEv;
- _ZN7android9RpcServer13getRootObjectEv;
- _ZN7android9RpcServer13releaseServerEv;
- _ZN7android9RpcServer13setMaxThreadsEj;
- _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android9RpcServer15setupInetServerEjPj;
- _ZN7android9RpcServer16setupVsockServerEj;
- _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
- _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
- _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
- _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
- _ZN7android9RpcServer21setupUnixDomainServerEPKc;
- _ZN7android9RpcServer24numUninitializedSessionsEv;
- _ZN7android9RpcServer4joinEv;
- _ZN7android9RpcServer4makeEv;
- _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
- _ZN7android9RpcServer9acceptOneEv;
- _ZN7android9RpcServer9hasServerEv;
- _ZN7android9RpcServerC1Ev;
- _ZN7android9RpcServerC2Ev;
- _ZN7android9RpcServerD0Ev;
- _ZN7android9RpcServerD1Ev;
- _ZN7android9RpcServerD2Ev;
- _ZN7android9SingletonINS_15PermissionCacheEE11getInstanceEv;
- _ZN7android9SingletonINS_15PermissionCacheEE11hasInstanceEv;
- _ZN7android9SingletonINS_15PermissionCacheEE5sLockE;
- _ZN7android9SingletonINS_15PermissionCacheEE9sInstanceE;
- _ZN7android9SingletonINS_15PermissionCacheEEC1Ev;
- _ZN7android9SingletonINS_15PermissionCacheEEC2Ev;
- _ZN7android9SingletonINS_15PermissionCacheEED1Ev;
- _ZN7android9SingletonINS_15PermissionCacheEED2Ev;
- _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
- _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
- _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
- _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
- _ZNK7android10MemoryBase9getMemoryEPiPj;
- _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
- _ZNK7android10RpcAddress15viewRawEmbeddedEv;
- _ZNK7android10RpcAddress6isZeroEv;
- _ZNK7android10RpcAddress8toStringEv;
- _ZNK7android10RpcAddressltERKS0_;
- _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
- _ZNK7android12BpMemoryHeap12assertMappedEv;
- _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
- _ZNK7android12BpMemoryHeap7getBaseEv;
- _ZNK7android12BpMemoryHeap7getSizeEv;
- _ZNK7android12BpMemoryHeap8getFlagsEv;
- _ZNK7android12BpMemoryHeap9getHeapIDEv;
- _ZNK7android12BpMemoryHeap9getOffsetEv;
- _ZNK7android12MemoryDealer4dumpEPKc;
- _ZNK7android12MemoryDealer4heapEv;
- _ZNK7android12MemoryDealer9allocatorEv;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_compareEPKvS5_;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE15do_move_forwardEPvPKvj;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE16do_move_backwardEPvPKvj;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE7do_copyEPvPKvj;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE8do_splatEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_j;
- _ZNK7android12SortedVectorINS_8String16EE10do_compareEPKvS4_;
- _ZNK7android12SortedVectorINS_8String16EE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_8String16EE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_8String16EE15do_move_forwardEPvPKvj;
- _ZNK7android12SortedVectorINS_8String16EE16do_move_backwardEPvPKvj;
- _ZNK7android12SortedVectorINS_8String16EE7do_copyEPvPKvj;
- _ZNK7android12SortedVectorINS_8String16EE8do_splatEPvPKvj;
- _ZNK7android14IPCThreadState13getCallingPidEv;
- _ZNK7android14IPCThreadState13getCallingSidEv;
- _ZNK7android14IPCThreadState13getCallingUidEv;
- _ZNK7android14IPCThreadState18getCallRestrictionEv;
- _ZNK7android14IPCThreadState19getStrictModePolicyEv;
- _ZNK7android14IPCThreadState22getServingStackPointerEv;
- _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
- _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
- _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
- _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
- _ZNK7android14MemoryHeapBase7getBaseEv;
- _ZNK7android14MemoryHeapBase7getSizeEv;
- _ZNK7android14MemoryHeapBase8getFlagsEv;
- _ZNK7android14MemoryHeapBase9getDeviceEv;
- _ZNK7android14MemoryHeapBase9getHeapIDEv;
- _ZNK7android14MemoryHeapBase9getOffsetEv;
- _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
- _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android15PermissionCache5checkEPbRKNS_8String16Ej;
- _ZNK7android18BufferedTextOutput9getBufferEv;
- _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
- _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
- _ZNK7android21IPermissionController22getInterfaceDescriptorEv;
- _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
- _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
- _ZNK7android22SimpleBestFitAllocator4sizeEv;
- _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
- _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
- _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
- _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
- _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
- _ZNK7android2os17PersistableBundle10getIntKeysEv;
- _ZNK7android2os17PersistableBundle11getLongKeysEv;
- _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
- _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIxNS5_9allocatorIxEEEE;
- _ZNK7android2os17PersistableBundle13getStringKeysEv;
- _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
- _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
- _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
- _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
- _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
- _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
- _ZNK7android2os17PersistableBundle4sizeEv;
- _ZNK7android2os17PersistableBundle5emptyEv;
- _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
- _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPx;
- _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
- _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
- _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status9toString8Ev;
- _ZNK7android6Parcel10errorCheckEv;
- _ZNK7android6Parcel10ipcObjectsEv;
- _ZNK7android6Parcel10readDoubleEPd;
- _ZNK7android6Parcel10readDoubleEv;
- _ZNK7android6Parcel10readObjectEb;
- _ZNK7android6Parcel10readUint32EPj;
- _ZNK7android6Parcel10readUint32Ev;
- _ZNK7android6Parcel10readUint64EPy;
- _ZNK7android6Parcel10readUint64Ev;
- _ZNK7android6Parcel10scanForFdsEv;
- _ZNK7android6Parcel11ipcDataSizeEv;
- _ZNK7android6Parcel11readCStringEv;
- _ZNK7android6Parcel11readInplaceEj;
- _ZNK7android6Parcel11readPointerEPj;
- _ZNK7android6Parcel11readPointerEv;
- _ZNK7android6Parcel11readString8EPNS_7String8E;
- _ZNK7android6Parcel11readString8Ev;
- _ZNK7android6Parcel12dataCapacityEv;
- _ZNK7android6Parcel12dataPositionEv;
- _ZNK7android6Parcel12objectsCountEv;
- _ZNK7android6Parcel12readString16EPNS_8String16E;
- _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
- _ZNK7android6Parcel12readString16Ev;
- _ZNK7android6Parcel13markSensitiveEv;
- _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
- _ZNK7android6Parcel15ipcObjectsCountEv;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIxNS1_9allocatorIxEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
- _ZNK7android6Parcel15setDataPositionEj;
- _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16enforceInterfaceEPKDsjPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZNK7android6Parcel16readNativeHandleEv;
- _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16readStrongBinderEv;
- _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorIyNS1_9allocatorIyEEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
- _ZNK7android6Parcel16validateReadDataEj;
- _ZNK7android6Parcel17getBlobAshmemSizeEv;
- _ZNK7android6Parcel17getOpenAshmemSizeEv;
- _ZNK7android6Parcel17readExceptionCodeEv;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZNK7android6Parcel18hasFileDescriptorsEv;
- _ZNK7android6Parcel18readFileDescriptorEv;
- _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZNK7android6Parcel18readString8InplaceEPj;
- _ZNK7android6Parcel19readString16InplaceEPj;
- _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZNK7android6Parcel24readCallingWorkSourceUidEv;
- _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel24readParcelFileDescriptorEv;
- _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
- _ZNK7android6Parcel4dataEv;
- _ZNK7android6Parcel4readEPvj;
- _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
- _ZNK7android6Parcel5printERNS_10TextOutputEj;
- _ZNK7android6Parcel7ipcDataEv;
- _ZNK7android6Parcel8allowFdsEv;
- _ZNK7android6Parcel8dataSizeEv;
- _ZNK7android6Parcel8isForRpcEv;
- _ZNK7android6Parcel8readBlobEjPNS0_12ReadableBlobE;
- _ZNK7android6Parcel8readBoolEPb;
- _ZNK7android6Parcel8readBoolEv;
- _ZNK7android6Parcel8readByteEPa;
- _ZNK7android6Parcel8readByteEv;
- _ZNK7android6Parcel8readCharEPDs;
- _ZNK7android6Parcel8readCharEv;
- _ZNK7android6Parcel9dataAvailEv;
- _ZNK7android6Parcel9readFloatEPf;
- _ZNK7android6Parcel9readFloatEv;
- _ZNK7android6Parcel9readInt32EPi;
- _ZNK7android6Parcel9readInt32Ev;
- _ZNK7android6Parcel9readInt64EPx;
- _ZNK7android6Parcel9readInt64Ev;
- _ZNK7android6VectorIiE10do_destroyEPvj;
- _ZNK7android6VectorIiE12do_constructEPvj;
- _ZNK7android6VectorIiE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIiE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIiE7do_copyEPvPKvj;
- _ZNK7android6VectorIiE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_8String16EE10do_destroyEPvj;
- _ZNK7android6VectorINS_8String16EE12do_constructEPvj;
- _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvj;
- _ZNK7android7BBinder10findObjectEPKv;
- _ZNK7android7BBinder13isBinderAliveEv;
- _ZNK7android7BBinder22getInterfaceDescriptorEv;
- _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
- _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
- _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
- _ZNK7android7IBinder13checkSubclassEPKv;
- _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEi;
- _ZNK7android7IMemory15unsecurePointerEv;
- _ZNK7android7IMemory22getInterfaceDescriptorEv;
- _ZNK7android7IMemory4sizeEv;
- _ZNK7android7IMemory6offsetEv;
- _ZNK7android7IMemory7pointerEv;
- _ZNK7android8BpBinder10findObjectEPKv;
- _ZNK7android8BpBinder10rpcAddressEv;
- _ZNK7android8BpBinder10rpcSessionEv;
- _ZNK7android8BpBinder11isRpcBinderEv;
- _ZNK7android8BpBinder12binderHandleEv;
- _ZNK7android8BpBinder13isBinderAliveEv;
- _ZNK7android8BpBinder13ObjectManager4findEPKv;
- _ZNK7android8BpBinder18isDescriptorCachedEv;
- _ZNK7android8BpBinder22getInterfaceDescriptorEv;
- _ZNK7android8BpMemory9getMemoryEPiPj;
- _ZTCN7android10AllocationE0_NS_10IInterfaceE;
- _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
- _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10AllocationE0_NS_7IMemoryE;
- _ZTCN7android10AllocationE0_NS_8BnMemoryE;
- _ZTCN7android10AllocationE4_NS_7BBinderE;
- _ZTCN7android10AllocationE4_NS_7IBinderE;
- _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
- _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
- _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
- _ZTCN7android10MemoryBaseE4_NS_7BBinderE;
- _ZTCN7android10MemoryBaseE4_NS_7IBinderE;
- _ZTCN7android10PoolThreadE0_NS_6ThreadE;
- _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BnMemoryHeapE4_NS_7BBinderE;
- _ZTCN7android12BnMemoryHeapE4_NS_7IBinderE;
- _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BpMemoryHeapE4_NS_9BpRefBaseE;
- _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE32_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE32_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android14MemoryHeapBaseE32_NS_11IMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE32_NS_12BnMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE36_NS_7BBinderE;
- _ZTCN7android14MemoryHeapBaseE36_NS_7IBinderE;
- _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BnShellCallbackE4_NS_7BBinderE;
- _ZTCN7android15BnShellCallbackE4_NS_7IBinderE;
- _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BpShellCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BnResultReceiverE4_NS_7BBinderE;
- _ZTCN7android16BnResultReceiverE4_NS_7IBinderE;
- _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BpResultReceiverE4_NS_9BpRefBaseE;
- _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
- _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
- _ZTCN7android21IPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BnPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BnPermissionControllerE0_NS_11BnInterfaceINS_21IPermissionControllerEEE;
- _ZTCN7android22BnPermissionControllerE0_NS_21IPermissionControllerE;
- _ZTCN7android22BnPermissionControllerE4_NS_7BBinderE;
- _ZTCN7android22BnPermissionControllerE4_NS_7IBinderE;
- _ZTCN7android22BpPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BpPermissionControllerE0_NS_11BpInterfaceINS_21IPermissionControllerEEE;
- _ZTCN7android22BpPermissionControllerE0_NS_21IPermissionControllerE;
- _ZTCN7android22BpPermissionControllerE4_NS_9BpRefBaseE;
- _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BnClientCallbackE4_NS_7BBinderE;
- _ZTCN7android2os16BnClientCallbackE4_NS_7IBinderE;
- _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BnServiceManagerE4_NS_7BBinderE;
- _ZTCN7android2os16BnServiceManagerE4_NS_7IBinderE;
- _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BpClientCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BpServiceManagerE4_NS_9BpRefBaseE;
- _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BnServiceCallbackE4_NS_7BBinderE;
- _ZTCN7android2os17BnServiceCallbackE4_NS_7IBinderE;
- _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BpServiceCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android7BBinderE0_NS_7IBinderE;
- _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7BBinderE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7IBinderE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE4_NS_9BpRefBaseE;
- _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7BBinderE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7IBinderE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE4_NS_9BpRefBaseE;
- _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BnMemoryE4_NS_7BBinderE;
- _ZTCN7android8BnMemoryE4_NS_7IBinderE;
- _ZTCN7android8BpBinderE0_NS_7IBinderE;
- _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BpMemoryE4_NS_9BpRefBaseE;
- _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
- _ZThn4_N7android10AllocationD0Ev;
- _ZThn4_N7android10AllocationD1Ev;
- _ZThn4_N7android10MemoryBaseD0Ev;
- _ZThn4_N7android10MemoryBaseD1Ev;
- _ZThn4_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android12BnMemoryHeapD0Ev;
- _ZThn4_N7android12BnMemoryHeapD1Ev;
- _ZThn4_N7android12BpMemoryHeapD0Ev;
- _ZThn4_N7android12BpMemoryHeapD1Ev;
- _ZThn4_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn4_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn4_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android8BnMemoryD0Ev;
- _ZThn4_N7android8BnMemoryD1Ev;
- _ZThn4_N7android8BpMemoryD0Ev;
- _ZThn4_N7android8BpMemoryD1Ev;
- _ZTTN7android10AllocationE;
- _ZTTN7android10IInterfaceE;
- _ZTTN7android10MemoryBaseE;
- _ZTTN7android10PoolThreadE;
- _ZTTN7android10RpcSessionE;
- _ZTTN7android11IMemoryHeapE;
- _ZTTN7android12BnMemoryHeapE;
- _ZTTN7android12BpMemoryHeapE;
- _ZTTN7android12ProcessStateE;
- _ZTTN7android14IShellCallbackE;
- _ZTTN7android14MemoryHeapBaseE;
- _ZTTN7android15BnShellCallbackE;
- _ZTTN7android15BpShellCallbackE;
- _ZTTN7android15IResultReceiverE;
- _ZTTN7android15IServiceManagerE;
- _ZTTN7android16BnResultReceiverE;
- _ZTTN7android16BpResultReceiverE;
- _ZTTN7android18ServiceManagerShimE;
- _ZTTN7android21IPermissionControllerE;
- _ZTTN7android22BnPermissionControllerE;
- _ZTTN7android22BpPermissionControllerE;
- _ZTTN7android2os15IClientCallbackE;
- _ZTTN7android2os15IServiceManagerE;
- _ZTTN7android2os16BnClientCallbackE;
- _ZTTN7android2os16BnServiceManagerE;
- _ZTTN7android2os16BpClientCallbackE;
- _ZTTN7android2os16BpServiceManagerE;
- _ZTTN7android2os16IServiceCallbackE;
- _ZTTN7android2os17BnServiceCallbackE;
- _ZTTN7android2os17BpServiceCallbackE;
- _ZTTN7android7BBinderE;
- _ZTTN7android7content2pm21IPackageManagerNativeE;
- _ZTTN7android7content2pm22BnPackageManagerNativeE;
- _ZTTN7android7content2pm22BpPackageManagerNativeE;
- _ZTTN7android7content2pm22IPackageChangeObserverE;
- _ZTTN7android7content2pm23BnPackageChangeObserverE;
- _ZTTN7android7content2pm23BpPackageChangeObserverE;
- _ZTTN7android7IBinderE;
- _ZTTN7android7IMemoryE;
- _ZTTN7android8BnMemoryE;
- _ZTTN7android8BpBinderE;
- _ZTTN7android8BpMemoryE;
- _ZTTN7android9BpRefBaseE;
- _ZTTN7android9HeapCacheE;
- _ZTTN7android9RpcServerE;
- _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
- _ZTv0_n12_N7android10AllocationD0Ev;
- _ZTv0_n12_N7android10AllocationD1Ev;
- _ZTv0_n12_N7android10IInterfaceD0Ev;
- _ZTv0_n12_N7android10IInterfaceD1Ev;
- _ZTv0_n12_N7android10MemoryBaseD0Ev;
- _ZTv0_n12_N7android10MemoryBaseD1Ev;
- _ZTv0_n12_N7android10RpcSessionD0Ev;
- _ZTv0_n12_N7android10RpcSessionD1Ev;
- _ZTv0_n12_N7android11IMemoryHeapD0Ev;
- _ZTv0_n12_N7android11IMemoryHeapD1Ev;
- _ZTv0_n12_N7android12BnMemoryHeapD0Ev;
- _ZTv0_n12_N7android12BnMemoryHeapD1Ev;
- _ZTv0_n12_N7android12BpMemoryHeapD0Ev;
- _ZTv0_n12_N7android12BpMemoryHeapD1Ev;
- _ZTv0_n12_N7android12ProcessStateD0Ev;
- _ZTv0_n12_N7android12ProcessStateD1Ev;
- _ZTv0_n12_N7android14IShellCallbackD0Ev;
- _ZTv0_n12_N7android14IShellCallbackD1Ev;
- _ZTv0_n12_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n12_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n12_N7android15IResultReceiverD0Ev;
- _ZTv0_n12_N7android15IResultReceiverD1Ev;
- _ZTv0_n12_N7android15IServiceManagerD0Ev;
- _ZTv0_n12_N7android15IServiceManagerD1Ev;
- _ZTv0_n12_N7android21IPermissionControllerD0Ev;
- _ZTv0_n12_N7android21IPermissionControllerD1Ev;
- _ZTv0_n12_N7android2os15IClientCallbackD0Ev;
- _ZTv0_n12_N7android2os15IClientCallbackD1Ev;
- _ZTv0_n12_N7android2os15IServiceManagerD0Ev;
- _ZTv0_n12_N7android2os15IServiceManagerD1Ev;
- _ZTv0_n12_N7android2os16IServiceCallbackD0Ev;
- _ZTv0_n12_N7android2os16IServiceCallbackD1Ev;
- _ZTv0_n12_N7android7BBinderD0Ev;
- _ZTv0_n12_N7android7BBinderD1Ev;
- _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD0Ev;
- _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD1Ev;
- _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD0Ev;
- _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD1Ev;
- _ZTv0_n12_N7android7IBinderD0Ev;
- _ZTv0_n12_N7android7IBinderD1Ev;
- _ZTv0_n12_N7android7IMemoryD0Ev;
- _ZTv0_n12_N7android7IMemoryD1Ev;
- _ZTv0_n12_N7android8BnMemoryD0Ev;
- _ZTv0_n12_N7android8BnMemoryD1Ev;
- _ZTv0_n12_N7android8BpBinderD0Ev;
- _ZTv0_n12_N7android8BpBinderD1Ev;
- _ZTv0_n12_N7android8BpMemoryD0Ev;
- _ZTv0_n12_N7android8BpMemoryD1Ev;
- _ZTv0_n12_N7android9BpRefBaseD0Ev;
- _ZTv0_n12_N7android9BpRefBaseD1Ev;
- _ZTv0_n12_N7android9HeapCacheD0Ev;
- _ZTv0_n12_N7android9HeapCacheD1Ev;
- _ZTv0_n12_N7android9RpcServerD0Ev;
- _ZTv0_n12_N7android9RpcServerD1Ev;
- _ZTv0_n16_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n16_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n16_N7android8BpBinder10onFirstRefEv;
- _ZTv0_n16_N7android9BpRefBase10onFirstRefEv;
- _ZTv0_n20_N7android8BpBinder15onLastStrongRefEPKv;
- _ZTv0_n20_N7android9BpRefBase15onLastStrongRefEPKv;
- _ZTv0_n24_N7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZTv0_n24_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZTv0_n28_NK7android14MemoryHeapBase9getHeapIDEv;
- _ZTv0_n32_NK7android14MemoryHeapBase7getBaseEv;
- _ZTv0_n36_NK7android14MemoryHeapBase7getSizeEv;
- _ZTv0_n40_NK7android14MemoryHeapBase8getFlagsEv;
- _ZTv0_n44_NK7android14MemoryHeapBase9getOffsetEv;
- _ZTvn4_n16_N7android14MemoryHeapBaseD0Ev;
- _ZTvn4_n16_N7android14MemoryHeapBaseD1Ev;
- _ZTVN7android10AllocationE;
- _ZTVN7android10IInterfaceE;
- _ZTVN7android10MemoryBaseE;
- _ZTVN7android10PoolThreadE;
- _ZTVN7android10RpcSession13RpcConnectionE;
- _ZTVN7android10RpcSessionE;
- _ZTVN7android10TextOutputE;
- _ZTVN7android11IMemoryHeapE;
- _ZTVN7android12BnMemoryHeapE;
- _ZTVN7android12BpMemoryHeapE;
- _ZTVN7android12FdTextOutputE;
- _ZTVN7android12MemoryDealerE;
- _ZTVN7android12ProcessStateE;
- _ZTVN7android12SortedVectorINS_15PermissionCache5EntryEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
- _ZTVN7android12SortedVectorINS_8String16EEE;
- _ZTVN7android13LogTextOutputE;
- _ZTVN7android14IShellCallbackE;
- _ZTVN7android14MemoryHeapBaseE;
- _ZTVN7android15BnShellCallbackE;
- _ZTVN7android15BpShellCallbackE;
- _ZTVN7android15IResultReceiverE;
- _ZTVN7android15IServiceManagerE;
- _ZTVN7android16BnResultReceiverE;
- _ZTVN7android16BpResultReceiverE;
- _ZTVN7android17InetSocketAddressE;
- _ZTVN7android17UnixSocketAddressE;
- _ZTVN7android18BufferedTextOutput11BufferStateE;
- _ZTVN7android18BufferedTextOutputE;
- _ZTVN7android18ServiceManagerShimE;
- _ZTVN7android18VsockSocketAddressE;
- _ZTVN7android21IPermissionControllerE;
- _ZTVN7android22BnPermissionControllerE;
- _ZTVN7android22BpPermissionControllerE;
- _ZTVN7android2os15IClientCallbackE;
- _ZTVN7android2os15IServiceManagerE;
- _ZTVN7android2os16BnClientCallbackE;
- _ZTVN7android2os16BnServiceManagerE;
- _ZTVN7android2os16BpClientCallbackE;
- _ZTVN7android2os16BpServiceManagerE;
- _ZTVN7android2os16IServiceCallbackE;
- _ZTVN7android2os16ParcelableHolderE;
- _ZTVN7android2os16ServiceDebugInfoE;
- _ZTVN7android2os17BnServiceCallbackE;
- _ZTVN7android2os17BpServiceCallbackE;
- _ZTVN7android2os17PersistableBundleE;
- _ZTVN7android2os20ParcelFileDescriptorE;
- _ZTVN7android6VectorIiEE;
- _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
- _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
- _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
- _ZTVN7android6VectorINS_8String16EEE;
- _ZTVN7android6VectorIPNS_7BBinderEEE;
- _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
- _ZTVN7android6VectorIPNS_7RefBaseEEE;
- _ZTVN7android7BBinderE;
- _ZTVN7android7content2pm18PackageChangeEventE;
- _ZTVN7android7content2pm21IPackageManagerNativeE;
- _ZTVN7android7content2pm22BnPackageManagerNativeE;
- _ZTVN7android7content2pm22BpPackageManagerNativeE;
- _ZTVN7android7content2pm22IPackageChangeObserverE;
- _ZTVN7android7content2pm23BnPackageChangeObserverE;
- _ZTVN7android7content2pm23BpPackageChangeObserverE;
- _ZTVN7android7IBinderE;
- _ZTVN7android7IMemoryE;
- _ZTVN7android8BnMemoryE;
- _ZTVN7android8BpBinderE;
- _ZTVN7android8BpMemoryE;
- _ZTVN7android9BpRefBaseE;
- _ZTVN7android9HeapCacheE;
- _ZTVN7android9RpcServerE;
- local:
- *;
-};
diff --git a/libs/binder/libbinder.arm32.vendor.map b/libs/binder/libbinder.arm32.vendor.map
deleted file mode 100644
index 5042414..0000000
--- a/libs/binder/libbinder.arm32.vendor.map
+++ /dev/null
@@ -1,1319 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
- global:
- getBinderKernelReferences;
- kDefaultDriver;
- _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
- _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
- _ZN7android10AllocationD0Ev;
- _ZN7android10AllocationD1Ev;
- _ZN7android10AllocationD2Ev;
- _ZN7android10IInterface8asBinderEPKS0_;
- _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
- _ZN7android10IInterfaceC2Ev;
- _ZN7android10IInterfaceD0Ev;
- _ZN7android10IInterfaceD1Ev;
- _ZN7android10IInterfaceD2Ev;
- _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij;
- _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEEij;
- _ZN7android10MemoryBaseD0Ev;
- _ZN7android10MemoryBaseD1Ev;
- _ZN7android10MemoryBaseD2Ev;
- _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
- _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
- _ZN7android10RpcAddress4zeroEv;
- _ZN7android10RpcAddress6uniqueEv;
- _ZN7android10RpcAddressC1Ev;
- _ZN7android10RpcAddressC2Ev;
- _ZN7android10RpcAddressD1Ev;
- _ZN7android10RpcAddressD2Ev;
- _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
- _ZN7android10RpcSession13getRootObjectEv;
- _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
- _ZN7android10RpcSession15setupInetClientEPKcj;
- _ZN7android10RpcSession15terminateLockedEv;
- _ZN7android10RpcSession16setupVsockClientEjj;
- _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
- _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEj;
- _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
- _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
- _ZN7android10RpcSession19getRemoteMaxThreadsEPj;
- _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
- _ZN7android10RpcSession21setupUnixDomainClientEPKc;
- _ZN7android10RpcSession22addNullDebuggingClientEv;
- _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
- _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4makeEv;
- _ZN7android10RpcSession6readIdEv;
- _ZN7android10RpcSession6serverEv;
- _ZN7android10RpcSession7preJoinENSt3__16threadE;
- _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
- _ZN7android10RpcSessionC1Ev;
- _ZN7android10RpcSessionC2Ev;
- _ZN7android10RpcSessionD0Ev;
- _ZN7android10RpcSessionD1Ev;
- _ZN7android10RpcSessionD2Ev;
- _ZN7android10TextOutputC2Ev;
- _ZN7android10TextOutputD0Ev;
- _ZN7android10TextOutputD1Ev;
- _ZN7android10TextOutputD2Ev;
- _ZN7android10zeroMemoryEPhj;
- _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
- _ZN7android11IMemoryHeap10descriptorE;
- _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android11IMemoryHeap12default_implE;
- _ZN7android11IMemoryHeap14getDefaultImplEv;
- _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android11IMemoryHeapC2Ev;
- _ZN7android11IMemoryHeapD0Ev;
- _ZN7android11IMemoryHeapD1Ev;
- _ZN7android11IMemoryHeapD2Ev;
- _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android12BnMemoryHeapC2Ev;
- _ZN7android12BnMemoryHeapD0Ev;
- _ZN7android12BnMemoryHeapD1Ev;
- _ZN7android12BnMemoryHeapD2Ev;
- _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapD0Ev;
- _ZN7android12BpMemoryHeapD1Ev;
- _ZN7android12BpMemoryHeapD2Ev;
- _ZN7android12gTextBuffersE;
- _ZN7android12MemoryDealer10deallocateEj;
- _ZN7android12MemoryDealer22getAllocationAlignmentEv;
- _ZN7android12MemoryDealer8allocateEj;
- _ZN7android12MemoryDealerC1EjPKcj;
- _ZN7android12MemoryDealerC2EjPKcj;
- _ZN7android12MemoryDealerD0Ev;
- _ZN7android12MemoryDealerD1Ev;
- _ZN7android12MemoryDealerD2Ev;
- _ZN7android12printHexDataEiPKvjjijbPFvPvPKcES2_;
- _ZN7android12ProcessState10selfOrNullEv;
- _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
- _ZN7android12ProcessState13getDriverNameEv;
- _ZN7android12ProcessState14initWithDriverEPKc;
- _ZN7android12ProcessState15startThreadPoolEv;
- _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android12ProcessState17spawnPooledThreadEb;
- _ZN7android12ProcessState18giveThreadPoolNameEv;
- _ZN7android12ProcessState18lookupHandleLockedEi;
- _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
- _ZN7android12ProcessState19getKernelReferencesEjPj;
- _ZN7android12ProcessState20becomeContextManagerEv;
- _ZN7android12ProcessState20makeBinderThreadNameEv;
- _ZN7android12ProcessState23getStrongProxyForHandleEi;
- _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
- _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
- _ZN7android12ProcessState27setThreadPoolMaxThreadCountEj;
- _ZN7android12ProcessState4initEPKcb;
- _ZN7android12ProcessState4selfEv;
- _ZN7android12ProcessStateC1EPKc;
- _ZN7android12ProcessStateC2EPKc;
- _ZN7android12ProcessStateD0Ev;
- _ZN7android12ProcessStateD1Ev;
- _ZN7android12ProcessStateD2Ev;
- _ZN7android13printTypeCodeEjPFvPvPKcES0_;
- _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhjPKyj;
- _ZN7android14IPCThreadState10selfOrNullEv;
- _ZN7android14IPCThreadState11clearCallerEv;
- _ZN7android14IPCThreadState11stopProcessEb;
- _ZN7android14IPCThreadState12setupPollingEPi;
- _ZN7android14IPCThreadState13decWeakHandleEi;
- _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
- _ZN7android14IPCThreadState13flushCommandsEv;
- _ZN7android14IPCThreadState13flushIfNeededEv;
- _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState14clearLastErrorEv;
- _ZN7android14IPCThreadState14executeCommandEi;
- _ZN7android14IPCThreadState14joinThreadPoolEb;
- _ZN7android14IPCThreadState14talkWithDriverEb;
- _ZN7android14IPCThreadState15decStrongHandleEi;
- _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
- _ZN7android14IPCThreadState16threadDestructorEPv;
- _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
- _ZN7android14IPCThreadState19setStrictModePolicyEi;
- _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
- _ZN7android14IPCThreadState20clearCallingIdentityEv;
- _ZN7android14IPCThreadState20getAndExecuteCommandEv;
- _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
- _ZN7android14IPCThreadState20handlePolledCommandsEv;
- _ZN7android14IPCThreadState20processPendingDerefsEv;
- _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
- _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
- _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
- _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState22processPostWriteDerefsEv;
- _ZN7android14IPCThreadState22restoreCallingIdentityEx;
- _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
- _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
- _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState24restoreCallingWorkSourceEx;
- _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
- _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
- _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
- _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
- _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
- _ZN7android14IPCThreadState4selfEv;
- _ZN7android14IPCThreadState6freezeEibj;
- _ZN7android14IPCThreadState7processEv;
- _ZN7android14IPCThreadState8shutdownEv;
- _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
- _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
- _ZN7android14IPCThreadStateC1Ev;
- _ZN7android14IPCThreadStateC2Ev;
- _ZN7android14IPCThreadStateD1Ev;
- _ZN7android14IPCThreadStateD2Ev;
- _ZN7android14IShellCallback10descriptorE;
- _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android14IShellCallback12default_implE;
- _ZN7android14IShellCallback14getDefaultImplEv;
- _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android14IShellCallbackC2Ev;
- _ZN7android14IShellCallbackD0Ev;
- _ZN7android14IShellCallbackD1Ev;
- _ZN7android14IShellCallbackD2Ev;
- _ZN7android14MemoryHeapBase4initEiPvjiPKc;
- _ZN7android14MemoryHeapBase5mapfdEibjl;
- _ZN7android14MemoryHeapBase7disposeEv;
- _ZN7android14MemoryHeapBaseC1Eijjl;
- _ZN7android14MemoryHeapBaseC1EjjPKc;
- _ZN7android14MemoryHeapBaseC1EPKcjj;
- _ZN7android14MemoryHeapBaseC1Ev;
- _ZN7android14MemoryHeapBaseC2Eijjl;
- _ZN7android14MemoryHeapBaseC2EjjPKc;
- _ZN7android14MemoryHeapBaseC2EPKcjj;
- _ZN7android14MemoryHeapBaseC2Ev;
- _ZN7android14MemoryHeapBaseD0Ev;
- _ZN7android14MemoryHeapBaseD1Ev;
- _ZN7android14MemoryHeapBaseD2Ev;
- _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android15IResultReceiver10descriptorE;
- _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android15IResultReceiver12default_implE;
- _ZN7android15IResultReceiver14getDefaultImplEv;
- _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android15IResultReceiverC2Ev;
- _ZN7android15IResultReceiverD0Ev;
- _ZN7android15IResultReceiverD1Ev;
- _ZN7android15IResultReceiverD2Ev;
- _ZN7android15IServiceManagerC2Ev;
- _ZN7android15IServiceManagerD0Ev;
- _ZN7android15IServiceManagerD1Ev;
- _ZN7android15IServiceManagerD2Ev;
- _ZN7android15stringForIndentEi;
- _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android18BufferedTextOutput10moveIndentEi;
- _ZN7android18BufferedTextOutput10pushBundleEv;
- _ZN7android18BufferedTextOutput5printEPKcj;
- _ZN7android18BufferedTextOutput9popBundleEv;
- _ZN7android18BufferedTextOutputC2Ej;
- _ZN7android18BufferedTextOutputD0Ev;
- _ZN7android18BufferedTextOutputD1Ev;
- _ZN7android18BufferedTextOutputD2Ev;
- _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
- _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
- _ZN7android18ServiceManagerShim12listServicesEi;
- _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
- _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
- _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
- _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18the_context_objectE;
- _ZN7android21defaultServiceManagerEv;
- _ZN7android22SimpleBestFitAllocator10deallocateEj;
- _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
- _ZN7android22SimpleBestFitAllocator5allocEjj;
- _ZN7android22SimpleBestFitAllocator7deallocEj;
- _ZN7android22SimpleBestFitAllocator8allocateEjj;
- _ZN7android22SimpleBestFitAllocatorC1Ej;
- _ZN7android22SimpleBestFitAllocatorC2Ej;
- _ZN7android22SimpleBestFitAllocatorD1Ev;
- _ZN7android22SimpleBestFitAllocatorD2Ev;
- _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
- _ZN7android2os15IClientCallback10descriptorE;
- _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IClientCallback12default_implE;
- _ZN7android2os15IClientCallback14getDefaultImplEv;
- _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IClientCallbackC2Ev;
- _ZN7android2os15IClientCallbackD0Ev;
- _ZN7android2os15IClientCallbackD1Ev;
- _ZN7android2os15IClientCallbackD2Ev;
- _ZN7android2os15IServiceManager10descriptorE;
- _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IServiceManager12default_implE;
- _ZN7android2os15IServiceManager14getDefaultImplEv;
- _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IServiceManagerC2Ev;
- _ZN7android2os15IServiceManagerD0Ev;
- _ZN7android2os15IServiceManagerD1Ev;
- _ZN7android2os15IServiceManagerD2Ev;
- _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnClientCallbackC2Ev;
- _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnServiceManagerC2Ev;
- _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
- _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
- _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
- _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
- _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
- _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
- _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
- _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
- _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback10descriptorE;
- _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback12default_implE;
- _ZN7android2os16IServiceCallback14getDefaultImplEv;
- _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os16IServiceCallbackC2Ev;
- _ZN7android2os16IServiceCallbackD0Ev;
- _ZN7android2os16IServiceCallbackD1Ev;
- _ZN7android2os16IServiceCallbackD2Ev;
- _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os17BnServiceCallbackC2Ev;
- _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
- _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIxNS5_9allocatorIxEEEE;
- _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEj;
- _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
- _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
- _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
- _ZN7android2os17PersistableBundle7putLongERKNS_8String16Ex;
- _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
- _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
- _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC1Ev;
- _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC2Ev;
- _ZN7android2os20ParcelFileDescriptorD0Ev;
- _ZN7android2os20ParcelFileDescriptorD1Ev;
- _ZN7android2os20ParcelFileDescriptorD2Ev;
- _ZN7android4aerrE;
- _ZN7android4alogE;
- _ZN7android4aoutE;
- _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
- _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
- _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
- _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
- _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
- _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder20LazyServiceRegistrarC1Ev;
- _ZN7android6binder20LazyServiceRegistrarC2Ev;
- _ZN7android6binder6Status11fromStatusTEi;
- _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
- _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
- _ZN7android6binder6Status14setFromStatusTEi;
- _ZN7android6binder6Status17exceptionToStringEi;
- _ZN7android6binder6Status17fromExceptionCodeEi;
- _ZN7android6binder6Status17fromExceptionCodeEiPKc;
- _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
- _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status24fromServiceSpecificErrorEi;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status2okEv;
- _ZN7android6binder6StatusC1Eii;
- _ZN7android6binder6StatusC1EiiRKNS_7String8E;
- _ZN7android6binder6StatusC2Eii;
- _ZN7android6binder6StatusC2EiiRKNS_7String8E;
- _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
- _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
- _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
- _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
- _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
- _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
- _ZN7android6Parcel10appendFromEPKS0_jj;
- _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
- _ZN7android6Parcel10writeFloatEf;
- _ZN7android6Parcel10writeInt32Ei;
- _ZN7android6Parcel10writeInt64Ex;
- _ZN7android6Parcel11compareDataERKS0_;
- _ZN7android6Parcel11finishWriteEj;
- _ZN7android6Parcel11setDataSizeEj;
- _ZN7android6Parcel11writeDoubleEd;
- _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
- _ZN7android6Parcel11writeUint32Ej;
- _ZN7android6Parcel11writeUint64Ey;
- _ZN7android6Parcel12pushAllowFdsEb;
- _ZN7android6Parcel12restartWriteEj;
- _ZN7android6Parcel12writeCStringEPKc;
- _ZN7android6Parcel12writeInplaceEj;
- _ZN7android6Parcel12writePointerEj;
- _ZN7android6Parcel12writeString8EPKcj;
- _ZN7android6Parcel12writeString8ERKNS_7String8E;
- _ZN7android6Parcel13continueWriteEj;
- _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13writeString16EPKDsj;
- _ZN7android6Parcel13writeString16ERKNS_8String16E;
- _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
- _ZN7android6Parcel13writeUnpaddedEPKvj;
- _ZN7android6Parcel14acquireObjectsEv;
- _ZN7android6Parcel14freeDataNoInitEv;
- _ZN7android6Parcel14releaseObjectsEv;
- _ZN7android6Parcel14writeByteArrayEjPKh;
- _ZN7android6Parcel15restoreAllowFdsEb;
- _ZN7android6Parcel15setDataCapacityEj;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZN7android6Parcel15writeInt32ArrayEjPKi;
- _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIxNS1_9allocatorIxEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
- _ZN7android6Parcel16writeNoExceptionEv;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
- _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorIyNS1_9allocatorIyEEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
- _ZN7android6Parcel18getGlobalAllocSizeEv;
- _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel19getGlobalAllocCountEv;
- _ZN7android6Parcel19ipcSetDataReferenceEPKhjPKyjPFvPS0_S2_jS4_jE;
- _ZN7android6Parcel19writeFileDescriptorEib;
- _ZN7android6Parcel19writeInterfaceTokenEPKDsj;
- _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
- _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZN7android6Parcel20closeFileDescriptorsEv;
- _ZN7android6Parcel22writeDupFileDescriptorEi;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZN7android6Parcel25writeParcelFileDescriptorEib;
- _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
- _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
- _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
- _ZN7android6Parcel4Blob4initEiPvjb;
- _ZN7android6Parcel4Blob5clearEv;
- _ZN7android6Parcel4Blob7releaseEv;
- _ZN7android6Parcel4BlobC1Ev;
- _ZN7android6Parcel4BlobC2Ev;
- _ZN7android6Parcel4BlobD1Ev;
- _ZN7android6Parcel4BlobD2Ev;
- _ZN7android6Parcel5writeEPKvj;
- _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
- _ZN7android6Parcel7setDataEPKhj;
- _ZN7android6Parcel8freeDataEv;
- _ZN7android6Parcel8growDataEj;
- _ZN7android6Parcel8setErrorEi;
- _ZN7android6Parcel9initStateEv;
- _ZN7android6Parcel9writeBlobEjbPNS0_12WritableBlobE;
- _ZN7android6Parcel9writeBoolEb;
- _ZN7android6Parcel9writeByteEa;
- _ZN7android6Parcel9writeCharEDs;
- _ZN7android6ParcelC1Ev;
- _ZN7android6ParcelC2Ev;
- _ZN7android6ParcelD1Ev;
- _ZN7android6ParcelD2Ev;
- _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinder10pingBinderEv;
- _ZN7android7BBinder11getDebugPidEv;
- _ZN7android7BBinder11isInheritRtEv;
- _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android7BBinder11localBinderEv;
- _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android7BBinder12detachObjectEPKv;
- _ZN7android7BBinder12getExtensionEv;
- _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
- _ZN7android7BBinder12setInheritRtEb;
- _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android7BBinder15isRequestingSidEv;
- _ZN7android7BBinder16setRequestingSidEb;
- _ZN7android7BBinder17getOrCreateExtrasEv;
- _ZN7android7BBinder21getMinSchedulerPolicyEv;
- _ZN7android7BBinder21setMinSchedulerPolicyEii;
- _ZN7android7BBinder23getMinSchedulerPriorityEv;
- _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinderC1Ev;
- _ZN7android7BBinderC2Ev;
- _ZN7android7BBinderD0Ev;
- _ZN7android7BBinderD1Ev;
- _ZN7android7BBinderD2Ev;
- _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
- _ZN7android7content2pm21IPackageManagerNative10descriptorE;
- _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm21IPackageManagerNative12default_implE;
- _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
- _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm21IPackageManagerNativeC2Ev;
- _ZN7android7content2pm21IPackageManagerNativeD0Ev;
- _ZN7android7content2pm21IPackageManagerNativeD1Ev;
- _ZN7android7content2pm21IPackageManagerNativeD2Ev;
- _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
- _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
- _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
- _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
- _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPx;
- _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
- _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
- _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
- _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver12default_implE;
- _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
- _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm22IPackageChangeObserverC2Ev;
- _ZN7android7content2pm22IPackageChangeObserverD0Ev;
- _ZN7android7content2pm22IPackageChangeObserverD1Ev;
- _ZN7android7content2pm22IPackageChangeObserverD2Ev;
- _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
- _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
- _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7HexDumpC1EPKvjj;
- _ZN7android7HexDumpC2EPKvjj;
- _ZN7android7IBinder11getDebugPidEPi;
- _ZN7android7IBinder11localBinderEv;
- _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
- _ZN7android7IBinder12remoteBinderEv;
- _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
- _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
- _ZN7android7IBinderC2Ev;
- _ZN7android7IBinderD0Ev;
- _ZN7android7IBinderD1Ev;
- _ZN7android7IBinderD2Ev;
- _ZN7android7IMemory10descriptorE;
- _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7IMemory12default_implE;
- _ZN7android7IMemory14getDefaultImplEv;
- _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android7IMemoryC2Ev;
- _ZN7android7IMemoryD0Ev;
- _ZN7android7IMemoryD1Ev;
- _ZN7android7IMemoryD2Ev;
- _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BnMemoryC2Ev;
- _ZN7android8BnMemoryD0Ev;
- _ZN7android8BnMemoryD1Ev;
- _ZN7android8BnMemoryD2Ev;
- _ZN7android8BpBinder10onFirstRefEv;
- _ZN7android8BpBinder10pingBinderEv;
- _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android8BpBinder12detachObjectEPKv;
- _ZN7android8BpBinder12remoteBinderEv;
- _ZN7android8BpBinder12sendObituaryEv;
- _ZN7android8BpBinder12sTrackingMapE;
- _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
- _ZN7android8BpBinder13ObjectManager4killEv;
- _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
- _ZN7android8BpBinder13ObjectManager6detachEPKv;
- _ZN7android8BpBinder13ObjectManagerC1Ev;
- _ZN7android8BpBinder13ObjectManagerC2Ev;
- _ZN7android8BpBinder13ObjectManagerD1Ev;
- _ZN7android8BpBinder13ObjectManagerD2Ev;
- _ZN7android8BpBinder13sTrackingLockE;
- _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
- _ZN7android8BpBinder14sLimitCallbackE;
- _ZN7android8BpBinder15onLastStrongRefEPKv;
- _ZN7android8BpBinder15sNumTrackedUidsE;
- _ZN7android8BpBinder16enableCountByUidEv;
- _ZN7android8BpBinder16setLimitCallbackEPFviE;
- _ZN7android8BpBinder17disableCountByUidEv;
- _ZN7android8BpBinder18sCountByUidEnabledE;
- _ZN7android8BpBinder19getBinderProxyCountEj;
- _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZN7android8BpBinder20setCountByUidEnabledEb;
- _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
- _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
- _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
- _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
- _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android8BpBinder6createEi;
- _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC1EONS0_9RpcHandleE;
- _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC2EONS0_9RpcHandleE;
- _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderD0Ev;
- _ZN7android8BpBinderD1Ev;
- _ZN7android8BpBinderD2Ev;
- _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryD0Ev;
- _ZN7android8BpMemoryD1Ev;
- _ZN7android8BpMemoryD2Ev;
- _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
- _ZN7android8internal9Stability11levelStringENS1_5LevelE;
- _ZN7android8internal9Stability13getLocalLevelEv;
- _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
- _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
- _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
- _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
- _ZN7android8internal9Stability8Category11debugStringEv;
- _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
- _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
- _ZN7android8RpcState11CommandDataC1Ej;
- _ZN7android8RpcState11CommandDataC2Ej;
- _ZN7android8RpcState12countBindersEv;
- _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
- _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
- _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPj;
- _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
- _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
- _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
- _ZN7android8RpcState4dumpEv;
- _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvj;
- _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvj;
- _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
- _ZN7android8RpcState9terminateEv;
- _ZN7android8RpcStateC1Ev;
- _ZN7android8RpcStateC2Ev;
- _ZN7android8RpcStateD1Ev;
- _ZN7android8RpcStateD2Ev;
- _ZN7android9BpRefBase10onFirstRefEv;
- _ZN7android9BpRefBase15onLastStrongRefEPKv;
- _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseD0Ev;
- _ZN7android9BpRefBaseD1Ev;
- _ZN7android9BpRefBaseD2Ev;
- _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCache10dump_heapsEv;
- _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCacheC1Ev;
- _ZN7android9HeapCacheC2Ev;
- _ZN7android9HeapCacheD0Ev;
- _ZN7android9HeapCacheD1Ev;
- _ZN7android9HeapCacheD2Ev;
- _ZN7android9hexStringEPKvj;
- _ZN7android9RpcServer12listSessionsEv;
- _ZN7android9RpcServer13getMaxThreadsEv;
- _ZN7android9RpcServer13getRootObjectEv;
- _ZN7android9RpcServer13releaseServerEv;
- _ZN7android9RpcServer13setMaxThreadsEj;
- _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android9RpcServer15setupInetServerEjPj;
- _ZN7android9RpcServer16setupVsockServerEj;
- _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
- _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
- _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
- _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
- _ZN7android9RpcServer21setupUnixDomainServerEPKc;
- _ZN7android9RpcServer24numUninitializedSessionsEv;
- _ZN7android9RpcServer4joinEv;
- _ZN7android9RpcServer4makeEv;
- _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
- _ZN7android9RpcServer9acceptOneEv;
- _ZN7android9RpcServer9hasServerEv;
- _ZN7android9RpcServerC1Ev;
- _ZN7android9RpcServerC2Ev;
- _ZN7android9RpcServerD0Ev;
- _ZN7android9RpcServerD1Ev;
- _ZN7android9RpcServerD2Ev;
- _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
- _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
- _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
- _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
- _ZNK7android10MemoryBase9getMemoryEPiPj;
- _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
- _ZNK7android10RpcAddress15viewRawEmbeddedEv;
- _ZNK7android10RpcAddress6isZeroEv;
- _ZNK7android10RpcAddress8toStringEv;
- _ZNK7android10RpcAddressltERKS0_;
- _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
- _ZNK7android12BpMemoryHeap12assertMappedEv;
- _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
- _ZNK7android12BpMemoryHeap7getBaseEv;
- _ZNK7android12BpMemoryHeap7getSizeEv;
- _ZNK7android12BpMemoryHeap8getFlagsEv;
- _ZNK7android12BpMemoryHeap9getHeapIDEv;
- _ZNK7android12BpMemoryHeap9getOffsetEv;
- _ZNK7android12MemoryDealer4dumpEPKc;
- _ZNK7android12MemoryDealer4heapEv;
- _ZNK7android12MemoryDealer9allocatorEv;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvj;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_j;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_j;
- _ZNK7android14IPCThreadState13getCallingPidEv;
- _ZNK7android14IPCThreadState13getCallingSidEv;
- _ZNK7android14IPCThreadState13getCallingUidEv;
- _ZNK7android14IPCThreadState18getCallRestrictionEv;
- _ZNK7android14IPCThreadState19getStrictModePolicyEv;
- _ZNK7android14IPCThreadState22getServingStackPointerEv;
- _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
- _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
- _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
- _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
- _ZNK7android14MemoryHeapBase7getBaseEv;
- _ZNK7android14MemoryHeapBase7getSizeEv;
- _ZNK7android14MemoryHeapBase8getFlagsEv;
- _ZNK7android14MemoryHeapBase9getDeviceEv;
- _ZNK7android14MemoryHeapBase9getHeapIDEv;
- _ZNK7android14MemoryHeapBase9getOffsetEv;
- _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
- _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android18BufferedTextOutput9getBufferEv;
- _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
- _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
- _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
- _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
- _ZNK7android22SimpleBestFitAllocator4sizeEv;
- _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
- _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
- _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
- _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
- _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
- _ZNK7android2os17PersistableBundle10getIntKeysEv;
- _ZNK7android2os17PersistableBundle11getLongKeysEv;
- _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
- _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIxNS5_9allocatorIxEEEE;
- _ZNK7android2os17PersistableBundle13getStringKeysEv;
- _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
- _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
- _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
- _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
- _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
- _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
- _ZNK7android2os17PersistableBundle4sizeEv;
- _ZNK7android2os17PersistableBundle5emptyEv;
- _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
- _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPx;
- _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
- _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
- _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status9toString8Ev;
- _ZNK7android6Parcel10errorCheckEv;
- _ZNK7android6Parcel10ipcObjectsEv;
- _ZNK7android6Parcel10readDoubleEPd;
- _ZNK7android6Parcel10readDoubleEv;
- _ZNK7android6Parcel10readObjectEb;
- _ZNK7android6Parcel10readUint32EPj;
- _ZNK7android6Parcel10readUint32Ev;
- _ZNK7android6Parcel10readUint64EPy;
- _ZNK7android6Parcel10readUint64Ev;
- _ZNK7android6Parcel10scanForFdsEv;
- _ZNK7android6Parcel11ipcDataSizeEv;
- _ZNK7android6Parcel11readCStringEv;
- _ZNK7android6Parcel11readInplaceEj;
- _ZNK7android6Parcel11readPointerEPj;
- _ZNK7android6Parcel11readPointerEv;
- _ZNK7android6Parcel11readString8EPNS_7String8E;
- _ZNK7android6Parcel11readString8Ev;
- _ZNK7android6Parcel12dataCapacityEv;
- _ZNK7android6Parcel12dataPositionEv;
- _ZNK7android6Parcel12objectsCountEv;
- _ZNK7android6Parcel12readString16EPNS_8String16E;
- _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
- _ZNK7android6Parcel12readString16Ev;
- _ZNK7android6Parcel13markSensitiveEv;
- _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
- _ZNK7android6Parcel15ipcObjectsCountEv;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIxNS1_9allocatorIxEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
- _ZNK7android6Parcel15setDataPositionEj;
- _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16enforceInterfaceEPKDsjPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZNK7android6Parcel16readNativeHandleEv;
- _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16readStrongBinderEv;
- _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorIyNS1_9allocatorIyEEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
- _ZNK7android6Parcel16validateReadDataEj;
- _ZNK7android6Parcel17getBlobAshmemSizeEv;
- _ZNK7android6Parcel17getOpenAshmemSizeEv;
- _ZNK7android6Parcel17readExceptionCodeEv;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZNK7android6Parcel18hasFileDescriptorsEv;
- _ZNK7android6Parcel18readFileDescriptorEv;
- _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZNK7android6Parcel18readString8InplaceEPj;
- _ZNK7android6Parcel19readString16InplaceEPj;
- _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZNK7android6Parcel24readCallingWorkSourceUidEv;
- _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel24readParcelFileDescriptorEv;
- _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
- _ZNK7android6Parcel4dataEv;
- _ZNK7android6Parcel4readEPvj;
- _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
- _ZNK7android6Parcel5printERNS_10TextOutputEj;
- _ZNK7android6Parcel7ipcDataEv;
- _ZNK7android6Parcel8allowFdsEv;
- _ZNK7android6Parcel8dataSizeEv;
- _ZNK7android6Parcel8isForRpcEv;
- _ZNK7android6Parcel8readBlobEjPNS0_12ReadableBlobE;
- _ZNK7android6Parcel8readBoolEPb;
- _ZNK7android6Parcel8readBoolEv;
- _ZNK7android6Parcel8readByteEPa;
- _ZNK7android6Parcel8readByteEv;
- _ZNK7android6Parcel8readCharEPDs;
- _ZNK7android6Parcel8readCharEv;
- _ZNK7android6Parcel9dataAvailEv;
- _ZNK7android6Parcel9readFloatEPf;
- _ZNK7android6Parcel9readFloatEv;
- _ZNK7android6Parcel9readInt32EPi;
- _ZNK7android6Parcel9readInt32Ev;
- _ZNK7android6Parcel9readInt64EPx;
- _ZNK7android6Parcel9readInt64Ev;
- _ZNK7android6VectorIiE10do_destroyEPvj;
- _ZNK7android6VectorIiE12do_constructEPvj;
- _ZNK7android6VectorIiE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIiE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIiE7do_copyEPvPKvj;
- _ZNK7android6VectorIiE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvj;
- _ZNK7android6VectorINS_8String16EE10do_destroyEPvj;
- _ZNK7android6VectorINS_8String16EE12do_constructEPvj;
- _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvj;
- _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvj;
- _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvj;
- _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvj;
- _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvj;
- _ZNK7android7BBinder10findObjectEPKv;
- _ZNK7android7BBinder13isBinderAliveEv;
- _ZNK7android7BBinder22getInterfaceDescriptorEv;
- _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
- _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
- _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
- _ZNK7android7IBinder13checkSubclassEPKv;
- _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEi;
- _ZNK7android7IMemory15unsecurePointerEv;
- _ZNK7android7IMemory22getInterfaceDescriptorEv;
- _ZNK7android7IMemory4sizeEv;
- _ZNK7android7IMemory6offsetEv;
- _ZNK7android7IMemory7pointerEv;
- _ZNK7android8BpBinder10findObjectEPKv;
- _ZNK7android8BpBinder10rpcAddressEv;
- _ZNK7android8BpBinder10rpcSessionEv;
- _ZNK7android8BpBinder11isRpcBinderEv;
- _ZNK7android8BpBinder12binderHandleEv;
- _ZNK7android8BpBinder13isBinderAliveEv;
- _ZNK7android8BpBinder13ObjectManager4findEPKv;
- _ZNK7android8BpBinder18isDescriptorCachedEv;
- _ZNK7android8BpBinder22getInterfaceDescriptorEv;
- _ZNK7android8BpMemory9getMemoryEPiPj;
- _ZTCN7android10AllocationE0_NS_10IInterfaceE;
- _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
- _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10AllocationE0_NS_7IMemoryE;
- _ZTCN7android10AllocationE0_NS_8BnMemoryE;
- _ZTCN7android10AllocationE4_NS_7BBinderE;
- _ZTCN7android10AllocationE4_NS_7IBinderE;
- _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
- _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
- _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
- _ZTCN7android10MemoryBaseE4_NS_7BBinderE;
- _ZTCN7android10MemoryBaseE4_NS_7IBinderE;
- _ZTCN7android10PoolThreadE0_NS_6ThreadE;
- _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BnMemoryHeapE4_NS_7BBinderE;
- _ZTCN7android12BnMemoryHeapE4_NS_7IBinderE;
- _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BpMemoryHeapE4_NS_9BpRefBaseE;
- _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE32_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE32_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android14MemoryHeapBaseE32_NS_11IMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE32_NS_12BnMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE36_NS_7BBinderE;
- _ZTCN7android14MemoryHeapBaseE36_NS_7IBinderE;
- _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BnShellCallbackE4_NS_7BBinderE;
- _ZTCN7android15BnShellCallbackE4_NS_7IBinderE;
- _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BpShellCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BnResultReceiverE4_NS_7BBinderE;
- _ZTCN7android16BnResultReceiverE4_NS_7IBinderE;
- _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BpResultReceiverE4_NS_9BpRefBaseE;
- _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
- _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
- _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BnClientCallbackE4_NS_7BBinderE;
- _ZTCN7android2os16BnClientCallbackE4_NS_7IBinderE;
- _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BnServiceManagerE4_NS_7BBinderE;
- _ZTCN7android2os16BnServiceManagerE4_NS_7IBinderE;
- _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BpClientCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BpServiceManagerE4_NS_9BpRefBaseE;
- _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BnServiceCallbackE4_NS_7BBinderE;
- _ZTCN7android2os17BnServiceCallbackE4_NS_7IBinderE;
- _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BpServiceCallbackE4_NS_9BpRefBaseE;
- _ZTCN7android7BBinderE0_NS_7IBinderE;
- _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7BBinderE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7IBinderE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE4_NS_9BpRefBaseE;
- _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7BBinderE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7IBinderE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE4_NS_9BpRefBaseE;
- _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BnMemoryE4_NS_7BBinderE;
- _ZTCN7android8BnMemoryE4_NS_7IBinderE;
- _ZTCN7android8BpBinderE0_NS_7IBinderE;
- _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BpMemoryE4_NS_9BpRefBaseE;
- _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
- _ZThn4_N7android10AllocationD0Ev;
- _ZThn4_N7android10AllocationD1Ev;
- _ZThn4_N7android10MemoryBaseD0Ev;
- _ZThn4_N7android10MemoryBaseD1Ev;
- _ZThn4_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android12BnMemoryHeapD0Ev;
- _ZThn4_N7android12BnMemoryHeapD1Ev;
- _ZThn4_N7android12BpMemoryHeapD0Ev;
- _ZThn4_N7android12BpMemoryHeapD1Ev;
- _ZThn4_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn4_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn4_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn4_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn4_N7android8BnMemoryD0Ev;
- _ZThn4_N7android8BnMemoryD1Ev;
- _ZThn4_N7android8BpMemoryD0Ev;
- _ZThn4_N7android8BpMemoryD1Ev;
- _ZTTN7android10AllocationE;
- _ZTTN7android10IInterfaceE;
- _ZTTN7android10MemoryBaseE;
- _ZTTN7android10PoolThreadE;
- _ZTTN7android10RpcSessionE;
- _ZTTN7android11IMemoryHeapE;
- _ZTTN7android12BnMemoryHeapE;
- _ZTTN7android12BpMemoryHeapE;
- _ZTTN7android12ProcessStateE;
- _ZTTN7android14IShellCallbackE;
- _ZTTN7android14MemoryHeapBaseE;
- _ZTTN7android15BnShellCallbackE;
- _ZTTN7android15BpShellCallbackE;
- _ZTTN7android15IResultReceiverE;
- _ZTTN7android15IServiceManagerE;
- _ZTTN7android16BnResultReceiverE;
- _ZTTN7android16BpResultReceiverE;
- _ZTTN7android18ServiceManagerShimE;
- _ZTTN7android2os15IClientCallbackE;
- _ZTTN7android2os15IServiceManagerE;
- _ZTTN7android2os16BnClientCallbackE;
- _ZTTN7android2os16BnServiceManagerE;
- _ZTTN7android2os16BpClientCallbackE;
- _ZTTN7android2os16BpServiceManagerE;
- _ZTTN7android2os16IServiceCallbackE;
- _ZTTN7android2os17BnServiceCallbackE;
- _ZTTN7android2os17BpServiceCallbackE;
- _ZTTN7android7BBinderE;
- _ZTTN7android7content2pm21IPackageManagerNativeE;
- _ZTTN7android7content2pm22BnPackageManagerNativeE;
- _ZTTN7android7content2pm22BpPackageManagerNativeE;
- _ZTTN7android7content2pm22IPackageChangeObserverE;
- _ZTTN7android7content2pm23BnPackageChangeObserverE;
- _ZTTN7android7content2pm23BpPackageChangeObserverE;
- _ZTTN7android7IBinderE;
- _ZTTN7android7IMemoryE;
- _ZTTN7android8BnMemoryE;
- _ZTTN7android8BpBinderE;
- _ZTTN7android8BpMemoryE;
- _ZTTN7android9BpRefBaseE;
- _ZTTN7android9HeapCacheE;
- _ZTTN7android9RpcServerE;
- _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
- _ZTv0_n12_N7android10AllocationD0Ev;
- _ZTv0_n12_N7android10AllocationD1Ev;
- _ZTv0_n12_N7android10IInterfaceD0Ev;
- _ZTv0_n12_N7android10IInterfaceD1Ev;
- _ZTv0_n12_N7android10MemoryBaseD0Ev;
- _ZTv0_n12_N7android10MemoryBaseD1Ev;
- _ZTv0_n12_N7android10RpcSessionD0Ev;
- _ZTv0_n12_N7android10RpcSessionD1Ev;
- _ZTv0_n12_N7android11IMemoryHeapD0Ev;
- _ZTv0_n12_N7android11IMemoryHeapD1Ev;
- _ZTv0_n12_N7android12BnMemoryHeapD0Ev;
- _ZTv0_n12_N7android12BnMemoryHeapD1Ev;
- _ZTv0_n12_N7android12BpMemoryHeapD0Ev;
- _ZTv0_n12_N7android12BpMemoryHeapD1Ev;
- _ZTv0_n12_N7android12ProcessStateD0Ev;
- _ZTv0_n12_N7android12ProcessStateD1Ev;
- _ZTv0_n12_N7android14IShellCallbackD0Ev;
- _ZTv0_n12_N7android14IShellCallbackD1Ev;
- _ZTv0_n12_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n12_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n12_N7android15IResultReceiverD0Ev;
- _ZTv0_n12_N7android15IResultReceiverD1Ev;
- _ZTv0_n12_N7android15IServiceManagerD0Ev;
- _ZTv0_n12_N7android15IServiceManagerD1Ev;
- _ZTv0_n12_N7android2os15IClientCallbackD0Ev;
- _ZTv0_n12_N7android2os15IClientCallbackD1Ev;
- _ZTv0_n12_N7android2os15IServiceManagerD0Ev;
- _ZTv0_n12_N7android2os15IServiceManagerD1Ev;
- _ZTv0_n12_N7android2os16IServiceCallbackD0Ev;
- _ZTv0_n12_N7android2os16IServiceCallbackD1Ev;
- _ZTv0_n12_N7android7BBinderD0Ev;
- _ZTv0_n12_N7android7BBinderD1Ev;
- _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD0Ev;
- _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD1Ev;
- _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD0Ev;
- _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD1Ev;
- _ZTv0_n12_N7android7IBinderD0Ev;
- _ZTv0_n12_N7android7IBinderD1Ev;
- _ZTv0_n12_N7android7IMemoryD0Ev;
- _ZTv0_n12_N7android7IMemoryD1Ev;
- _ZTv0_n12_N7android8BnMemoryD0Ev;
- _ZTv0_n12_N7android8BnMemoryD1Ev;
- _ZTv0_n12_N7android8BpBinderD0Ev;
- _ZTv0_n12_N7android8BpBinderD1Ev;
- _ZTv0_n12_N7android8BpMemoryD0Ev;
- _ZTv0_n12_N7android8BpMemoryD1Ev;
- _ZTv0_n12_N7android9BpRefBaseD0Ev;
- _ZTv0_n12_N7android9BpRefBaseD1Ev;
- _ZTv0_n12_N7android9HeapCacheD0Ev;
- _ZTv0_n12_N7android9HeapCacheD1Ev;
- _ZTv0_n12_N7android9RpcServerD0Ev;
- _ZTv0_n12_N7android9RpcServerD1Ev;
- _ZTv0_n16_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n16_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n16_N7android8BpBinder10onFirstRefEv;
- _ZTv0_n16_N7android9BpRefBase10onFirstRefEv;
- _ZTv0_n20_N7android8BpBinder15onLastStrongRefEPKv;
- _ZTv0_n20_N7android9BpRefBase15onLastStrongRefEPKv;
- _ZTv0_n24_N7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZTv0_n24_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZTv0_n28_NK7android14MemoryHeapBase9getHeapIDEv;
- _ZTv0_n32_NK7android14MemoryHeapBase7getBaseEv;
- _ZTv0_n36_NK7android14MemoryHeapBase7getSizeEv;
- _ZTv0_n40_NK7android14MemoryHeapBase8getFlagsEv;
- _ZTv0_n44_NK7android14MemoryHeapBase9getOffsetEv;
- _ZTvn4_n16_N7android14MemoryHeapBaseD0Ev;
- _ZTvn4_n16_N7android14MemoryHeapBaseD1Ev;
- _ZTVN7android10AllocationE;
- _ZTVN7android10IInterfaceE;
- _ZTVN7android10MemoryBaseE;
- _ZTVN7android10PoolThreadE;
- _ZTVN7android10RpcSession13RpcConnectionE;
- _ZTVN7android10RpcSessionE;
- _ZTVN7android10TextOutputE;
- _ZTVN7android11IMemoryHeapE;
- _ZTVN7android12BnMemoryHeapE;
- _ZTVN7android12BpMemoryHeapE;
- _ZTVN7android12FdTextOutputE;
- _ZTVN7android12MemoryDealerE;
- _ZTVN7android12ProcessStateE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
- _ZTVN7android13LogTextOutputE;
- _ZTVN7android14IShellCallbackE;
- _ZTVN7android14MemoryHeapBaseE;
- _ZTVN7android15BnShellCallbackE;
- _ZTVN7android15BpShellCallbackE;
- _ZTVN7android15IResultReceiverE;
- _ZTVN7android15IServiceManagerE;
- _ZTVN7android16BnResultReceiverE;
- _ZTVN7android16BpResultReceiverE;
- _ZTVN7android17InetSocketAddressE;
- _ZTVN7android17UnixSocketAddressE;
- _ZTVN7android18BufferedTextOutput11BufferStateE;
- _ZTVN7android18BufferedTextOutputE;
- _ZTVN7android18ServiceManagerShimE;
- _ZTVN7android18VsockSocketAddressE;
- _ZTVN7android2os15IClientCallbackE;
- _ZTVN7android2os15IServiceManagerE;
- _ZTVN7android2os16BnClientCallbackE;
- _ZTVN7android2os16BnServiceManagerE;
- _ZTVN7android2os16BpClientCallbackE;
- _ZTVN7android2os16BpServiceManagerE;
- _ZTVN7android2os16IServiceCallbackE;
- _ZTVN7android2os16ParcelableHolderE;
- _ZTVN7android2os16ServiceDebugInfoE;
- _ZTVN7android2os17BnServiceCallbackE;
- _ZTVN7android2os17BpServiceCallbackE;
- _ZTVN7android2os17PersistableBundleE;
- _ZTVN7android2os20ParcelFileDescriptorE;
- _ZTVN7android6VectorIiEE;
- _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
- _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
- _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
- _ZTVN7android6VectorINS_8String16EEE;
- _ZTVN7android6VectorIPNS_7BBinderEEE;
- _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
- _ZTVN7android6VectorIPNS_7RefBaseEEE;
- _ZTVN7android7BBinderE;
- _ZTVN7android7content2pm18PackageChangeEventE;
- _ZTVN7android7content2pm21IPackageManagerNativeE;
- _ZTVN7android7content2pm22BnPackageManagerNativeE;
- _ZTVN7android7content2pm22BpPackageManagerNativeE;
- _ZTVN7android7content2pm22IPackageChangeObserverE;
- _ZTVN7android7content2pm23BnPackageChangeObserverE;
- _ZTVN7android7content2pm23BpPackageChangeObserverE;
- _ZTVN7android7IBinderE;
- _ZTVN7android7IMemoryE;
- _ZTVN7android8BnMemoryE;
- _ZTVN7android8BpBinderE;
- _ZTVN7android8BpMemoryE;
- _ZTVN7android9BpRefBaseE;
- _ZTVN7android9HeapCacheE;
- _ZTVN7android9RpcServerE;
- local:
- *;
-};
diff --git a/libs/binder/libbinder.arm64.map b/libs/binder/libbinder.arm64.map
deleted file mode 100644
index 6211250..0000000
--- a/libs/binder/libbinder.arm64.map
+++ /dev/null
@@ -1,1395 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
- global:
- getBinderKernelReferences;
- kDefaultDriver;
- _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
- _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
- _ZN7android10AllocationD0Ev;
- _ZN7android10AllocationD1Ev;
- _ZN7android10AllocationD2Ev;
- _ZN7android10IInterface8asBinderEPKS0_;
- _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
- _ZN7android10IInterfaceC2Ev;
- _ZN7android10IInterfaceD0Ev;
- _ZN7android10IInterfaceD1Ev;
- _ZN7android10IInterfaceD2Ev;
- _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElm;
- _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEElm;
- _ZN7android10MemoryBaseD0Ev;
- _ZN7android10MemoryBaseD1Ev;
- _ZN7android10MemoryBaseD2Ev;
- _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
- _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
- _ZN7android10RpcAddress4zeroEv;
- _ZN7android10RpcAddress6uniqueEv;
- _ZN7android10RpcAddressC1Ev;
- _ZN7android10RpcAddressC2Ev;
- _ZN7android10RpcAddressD1Ev;
- _ZN7android10RpcAddressD2Ev;
- _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
- _ZN7android10RpcSession13getRootObjectEv;
- _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
- _ZN7android10RpcSession15setupInetClientEPKcj;
- _ZN7android10RpcSession15terminateLockedEv;
- _ZN7android10RpcSession16setupVsockClientEjj;
- _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
- _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEm;
- _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
- _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
- _ZN7android10RpcSession19getRemoteMaxThreadsEPm;
- _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
- _ZN7android10RpcSession21setupUnixDomainClientEPKc;
- _ZN7android10RpcSession22addNullDebuggingClientEv;
- _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
- _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4makeEv;
- _ZN7android10RpcSession6readIdEv;
- _ZN7android10RpcSession6serverEv;
- _ZN7android10RpcSession7preJoinENSt3__16threadE;
- _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
- _ZN7android10RpcSessionC1Ev;
- _ZN7android10RpcSessionC2Ev;
- _ZN7android10RpcSessionD0Ev;
- _ZN7android10RpcSessionD1Ev;
- _ZN7android10RpcSessionD2Ev;
- _ZN7android10TextOutputC2Ev;
- _ZN7android10TextOutputD0Ev;
- _ZN7android10TextOutputD1Ev;
- _ZN7android10TextOutputD2Ev;
- _ZN7android10zeroMemoryEPhm;
- _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_21IPermissionControllerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
- _ZN7android11IMemoryHeap10descriptorE;
- _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android11IMemoryHeap12default_implE;
- _ZN7android11IMemoryHeap14getDefaultImplEv;
- _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android11IMemoryHeapC2Ev;
- _ZN7android11IMemoryHeapD0Ev;
- _ZN7android11IMemoryHeapD1Ev;
- _ZN7android11IMemoryHeapD2Ev;
- _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android12BnMemoryHeapC2Ev;
- _ZN7android12BnMemoryHeapD0Ev;
- _ZN7android12BnMemoryHeapD1Ev;
- _ZN7android12BnMemoryHeapD2Ev;
- _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapD0Ev;
- _ZN7android12BpMemoryHeapD1Ev;
- _ZN7android12BpMemoryHeapD2Ev;
- _ZN7android12gTextBuffersE;
- _ZN7android12MemoryDealer10deallocateEm;
- _ZN7android12MemoryDealer22getAllocationAlignmentEv;
- _ZN7android12MemoryDealer8allocateEm;
- _ZN7android12MemoryDealerC1EmPKcj;
- _ZN7android12MemoryDealerC2EmPKcj;
- _ZN7android12MemoryDealerD0Ev;
- _ZN7android12MemoryDealerD1Ev;
- _ZN7android12MemoryDealerD2Ev;
- _ZN7android12printHexDataEiPKvmmimbPFvPvPKcES2_;
- _ZN7android12ProcessState10selfOrNullEv;
- _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
- _ZN7android12ProcessState13getDriverNameEv;
- _ZN7android12ProcessState14initWithDriverEPKc;
- _ZN7android12ProcessState15startThreadPoolEv;
- _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android12ProcessState17spawnPooledThreadEb;
- _ZN7android12ProcessState18giveThreadPoolNameEv;
- _ZN7android12ProcessState18lookupHandleLockedEi;
- _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
- _ZN7android12ProcessState19getKernelReferencesEmPm;
- _ZN7android12ProcessState20becomeContextManagerEv;
- _ZN7android12ProcessState20makeBinderThreadNameEv;
- _ZN7android12ProcessState23getStrongProxyForHandleEi;
- _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
- _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
- _ZN7android12ProcessState27setThreadPoolMaxThreadCountEm;
- _ZN7android12ProcessState4initEPKcb;
- _ZN7android12ProcessState4selfEv;
- _ZN7android12ProcessStateC1EPKc;
- _ZN7android12ProcessStateC2EPKc;
- _ZN7android12ProcessStateD0Ev;
- _ZN7android12ProcessStateD1Ev;
- _ZN7android12ProcessStateD2Ev;
- _ZN7android13printTypeCodeEjPFvPvPKcES0_;
- _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhmPKym;
- _ZN7android14IPCThreadState10selfOrNullEv;
- _ZN7android14IPCThreadState11clearCallerEv;
- _ZN7android14IPCThreadState11stopProcessEb;
- _ZN7android14IPCThreadState12setupPollingEPi;
- _ZN7android14IPCThreadState13decWeakHandleEi;
- _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
- _ZN7android14IPCThreadState13flushCommandsEv;
- _ZN7android14IPCThreadState13flushIfNeededEv;
- _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState14clearLastErrorEv;
- _ZN7android14IPCThreadState14executeCommandEi;
- _ZN7android14IPCThreadState14joinThreadPoolEb;
- _ZN7android14IPCThreadState14talkWithDriverEb;
- _ZN7android14IPCThreadState15decStrongHandleEi;
- _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
- _ZN7android14IPCThreadState16threadDestructorEPv;
- _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
- _ZN7android14IPCThreadState19setStrictModePolicyEi;
- _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
- _ZN7android14IPCThreadState20clearCallingIdentityEv;
- _ZN7android14IPCThreadState20getAndExecuteCommandEv;
- _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
- _ZN7android14IPCThreadState20handlePolledCommandsEv;
- _ZN7android14IPCThreadState20processPendingDerefsEv;
- _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
- _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
- _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
- _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState22processPostWriteDerefsEv;
- _ZN7android14IPCThreadState22restoreCallingIdentityEl;
- _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
- _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
- _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState24restoreCallingWorkSourceEl;
- _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
- _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
- _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
- _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
- _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
- _ZN7android14IPCThreadState4selfEv;
- _ZN7android14IPCThreadState6freezeEibj;
- _ZN7android14IPCThreadState7processEv;
- _ZN7android14IPCThreadState8shutdownEv;
- _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
- _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
- _ZN7android14IPCThreadStateC1Ev;
- _ZN7android14IPCThreadStateC2Ev;
- _ZN7android14IPCThreadStateD1Ev;
- _ZN7android14IPCThreadStateD2Ev;
- _ZN7android14IShellCallback10descriptorE;
- _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android14IShellCallback12default_implE;
- _ZN7android14IShellCallback14getDefaultImplEv;
- _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android14IShellCallbackC2Ev;
- _ZN7android14IShellCallbackD0Ev;
- _ZN7android14IShellCallbackD1Ev;
- _ZN7android14IShellCallbackD2Ev;
- _ZN7android14MemoryHeapBase4initEiPvmiPKc;
- _ZN7android14MemoryHeapBase5mapfdEibml;
- _ZN7android14MemoryHeapBase7disposeEv;
- _ZN7android14MemoryHeapBaseC1Eimjl;
- _ZN7android14MemoryHeapBaseC1EmjPKc;
- _ZN7android14MemoryHeapBaseC1EPKcmj;
- _ZN7android14MemoryHeapBaseC1Ev;
- _ZN7android14MemoryHeapBaseC2Eimjl;
- _ZN7android14MemoryHeapBaseC2EmjPKc;
- _ZN7android14MemoryHeapBaseC2EPKcmj;
- _ZN7android14MemoryHeapBaseC2Ev;
- _ZN7android14MemoryHeapBaseD0Ev;
- _ZN7android14MemoryHeapBaseD1Ev;
- _ZN7android14MemoryHeapBaseD2Ev;
- _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android15checkPermissionERKNS_8String16Eij;
- _ZN7android15IResultReceiver10descriptorE;
- _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android15IResultReceiver12default_implE;
- _ZN7android15IResultReceiver14getDefaultImplEv;
- _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android15IResultReceiverC2Ev;
- _ZN7android15IResultReceiverD0Ev;
- _ZN7android15IResultReceiverD1Ev;
- _ZN7android15IResultReceiverD2Ev;
- _ZN7android15IServiceManagerC2Ev;
- _ZN7android15IServiceManagerD0Ev;
- _ZN7android15IServiceManagerD1Ev;
- _ZN7android15IServiceManagerD2Ev;
- _ZN7android15PermissionCache10purgeCacheEv;
- _ZN7android15PermissionCache15checkPermissionERKNS_8String16Eij;
- _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16E;
- _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16EPiS4_;
- _ZN7android15PermissionCache5cacheERKNS_8String16Ejb;
- _ZN7android15PermissionCache5purgeEv;
- _ZN7android15PermissionCacheC1Ev;
- _ZN7android15PermissionCacheC2Ev;
- _ZN7android15stringForIndentEi;
- _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android18BufferedTextOutput10moveIndentEi;
- _ZN7android18BufferedTextOutput10pushBundleEv;
- _ZN7android18BufferedTextOutput5printEPKcm;
- _ZN7android18BufferedTextOutput9popBundleEv;
- _ZN7android18BufferedTextOutputC2Ej;
- _ZN7android18BufferedTextOutputD0Ev;
- _ZN7android18BufferedTextOutputD1Ev;
- _ZN7android18BufferedTextOutputD2Ev;
- _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
- _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
- _ZN7android18ServiceManagerShim12listServicesEi;
- _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
- _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
- _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
- _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18the_context_objectE;
- _ZN7android20PermissionController10getServiceEv;
- _ZN7android20PermissionController13getPackageUidERKNS_8String16Ei;
- _ZN7android20PermissionController15checkPermissionERKNS_8String16Eii;
- _ZN7android20PermissionController17getPackagesForUidEjRNS_6VectorINS_8String16EEE;
- _ZN7android20PermissionController19isRuntimePermissionERKNS_8String16E;
- _ZN7android20PermissionController6noteOpERKNS_8String16EiS3_;
- _ZN7android20PermissionControllerC1Ev;
- _ZN7android20PermissionControllerC2Ev;
- _ZN7android21defaultServiceManagerEv;
- _ZN7android21IPermissionController10descriptorE;
- _ZN7android21IPermissionController11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android21IPermissionController12default_implE;
- _ZN7android21IPermissionController14getDefaultImplEv;
- _ZN7android21IPermissionController14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android21IPermissionControllerC2Ev;
- _ZN7android21IPermissionControllerD0Ev;
- _ZN7android21IPermissionControllerD1Ev;
- _ZN7android21IPermissionControllerD2Ev;
- _ZN7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android22checkCallingPermissionERKNS_8String16E;
- _ZN7android22checkCallingPermissionERKNS_8String16EPiS3_;
- _ZN7android22SimpleBestFitAllocator10deallocateEm;
- _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
- _ZN7android22SimpleBestFitAllocator5allocEmj;
- _ZN7android22SimpleBestFitAllocator7deallocEm;
- _ZN7android22SimpleBestFitAllocator8allocateEmj;
- _ZN7android22SimpleBestFitAllocatorC1Em;
- _ZN7android22SimpleBestFitAllocatorC2Em;
- _ZN7android22SimpleBestFitAllocatorD1Ev;
- _ZN7android22SimpleBestFitAllocatorD2Ev;
- _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
- _ZN7android2os15IClientCallback10descriptorE;
- _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IClientCallback12default_implE;
- _ZN7android2os15IClientCallback14getDefaultImplEv;
- _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IClientCallbackC2Ev;
- _ZN7android2os15IClientCallbackD0Ev;
- _ZN7android2os15IClientCallbackD1Ev;
- _ZN7android2os15IClientCallbackD2Ev;
- _ZN7android2os15IServiceManager10descriptorE;
- _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IServiceManager12default_implE;
- _ZN7android2os15IServiceManager14getDefaultImplEv;
- _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IServiceManagerC2Ev;
- _ZN7android2os15IServiceManagerD0Ev;
- _ZN7android2os15IServiceManagerD1Ev;
- _ZN7android2os15IServiceManagerD2Ev;
- _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnClientCallbackC2Ev;
- _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnServiceManagerC2Ev;
- _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
- _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
- _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
- _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
- _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
- _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
- _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
- _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
- _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback10descriptorE;
- _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback12default_implE;
- _ZN7android2os16IServiceCallback14getDefaultImplEv;
- _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os16IServiceCallbackC2Ev;
- _ZN7android2os16IServiceCallbackD0Ev;
- _ZN7android2os16IServiceCallbackD1Ev;
- _ZN7android2os16IServiceCallbackD2Ev;
- _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os17BnServiceCallbackC2Ev;
- _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
- _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIlNS5_9allocatorIlEEEE;
- _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEm;
- _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
- _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
- _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
- _ZN7android2os17PersistableBundle7putLongERKNS_8String16El;
- _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
- _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
- _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC1Ev;
- _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC2Ev;
- _ZN7android2os20ParcelFileDescriptorD0Ev;
- _ZN7android2os20ParcelFileDescriptorD1Ev;
- _ZN7android2os20ParcelFileDescriptorD2Ev;
- _ZN7android4aerrE;
- _ZN7android4alogE;
- _ZN7android4aoutE;
- _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
- _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
- _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
- _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
- _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
- _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder20LazyServiceRegistrarC1Ev;
- _ZN7android6binder20LazyServiceRegistrarC2Ev;
- _ZN7android6binder6Status11fromStatusTEi;
- _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
- _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
- _ZN7android6binder6Status14setFromStatusTEi;
- _ZN7android6binder6Status17exceptionToStringEi;
- _ZN7android6binder6Status17fromExceptionCodeEi;
- _ZN7android6binder6Status17fromExceptionCodeEiPKc;
- _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
- _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status24fromServiceSpecificErrorEi;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status2okEv;
- _ZN7android6binder6StatusC1Eii;
- _ZN7android6binder6StatusC1EiiRKNS_7String8E;
- _ZN7android6binder6StatusC2Eii;
- _ZN7android6binder6StatusC2EiiRKNS_7String8E;
- _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
- _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
- _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
- _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
- _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
- _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
- _ZN7android6Parcel10appendFromEPKS0_mm;
- _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
- _ZN7android6Parcel10writeFloatEf;
- _ZN7android6Parcel10writeInt32Ei;
- _ZN7android6Parcel10writeInt64El;
- _ZN7android6Parcel11compareDataERKS0_;
- _ZN7android6Parcel11finishWriteEm;
- _ZN7android6Parcel11setDataSizeEm;
- _ZN7android6Parcel11writeDoubleEd;
- _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
- _ZN7android6Parcel11writeUint32Ej;
- _ZN7android6Parcel11writeUint64Em;
- _ZN7android6Parcel12pushAllowFdsEb;
- _ZN7android6Parcel12restartWriteEm;
- _ZN7android6Parcel12writeCStringEPKc;
- _ZN7android6Parcel12writeInplaceEm;
- _ZN7android6Parcel12writePointerEm;
- _ZN7android6Parcel12writeString8EPKcm;
- _ZN7android6Parcel12writeString8ERKNS_7String8E;
- _ZN7android6Parcel13continueWriteEm;
- _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13writeString16EPKDsm;
- _ZN7android6Parcel13writeString16ERKNS_8String16E;
- _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
- _ZN7android6Parcel13writeUnpaddedEPKvm;
- _ZN7android6Parcel14acquireObjectsEv;
- _ZN7android6Parcel14freeDataNoInitEv;
- _ZN7android6Parcel14releaseObjectsEv;
- _ZN7android6Parcel14writeByteArrayEmPKh;
- _ZN7android6Parcel15restoreAllowFdsEb;
- _ZN7android6Parcel15setDataCapacityEm;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZN7android6Parcel15writeInt32ArrayEmPKi;
- _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIlNS1_9allocatorIlEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
- _ZN7android6Parcel16writeNoExceptionEv;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
- _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorImNS1_9allocatorImEEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
- _ZN7android6Parcel18getGlobalAllocSizeEv;
- _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel19getGlobalAllocCountEv;
- _ZN7android6Parcel19ipcSetDataReferenceEPKhmPKymPFvPS0_S2_mS4_mE;
- _ZN7android6Parcel19writeFileDescriptorEib;
- _ZN7android6Parcel19writeInterfaceTokenEPKDsm;
- _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
- _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZN7android6Parcel20closeFileDescriptorsEv;
- _ZN7android6Parcel22writeDupFileDescriptorEi;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZN7android6Parcel25writeParcelFileDescriptorEib;
- _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
- _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
- _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
- _ZN7android6Parcel4Blob4initEiPvmb;
- _ZN7android6Parcel4Blob5clearEv;
- _ZN7android6Parcel4Blob7releaseEv;
- _ZN7android6Parcel4BlobC1Ev;
- _ZN7android6Parcel4BlobC2Ev;
- _ZN7android6Parcel4BlobD1Ev;
- _ZN7android6Parcel4BlobD2Ev;
- _ZN7android6Parcel5writeEPKvm;
- _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
- _ZN7android6Parcel7setDataEPKhm;
- _ZN7android6Parcel8freeDataEv;
- _ZN7android6Parcel8growDataEm;
- _ZN7android6Parcel8setErrorEi;
- _ZN7android6Parcel9initStateEv;
- _ZN7android6Parcel9writeBlobEmbPNS0_12WritableBlobE;
- _ZN7android6Parcel9writeBoolEb;
- _ZN7android6Parcel9writeByteEa;
- _ZN7android6Parcel9writeCharEDs;
- _ZN7android6ParcelC1Ev;
- _ZN7android6ParcelC2Ev;
- _ZN7android6ParcelD1Ev;
- _ZN7android6ParcelD2Ev;
- _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinder10pingBinderEv;
- _ZN7android7BBinder11getDebugPidEv;
- _ZN7android7BBinder11isInheritRtEv;
- _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android7BBinder11localBinderEv;
- _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android7BBinder12detachObjectEPKv;
- _ZN7android7BBinder12getExtensionEv;
- _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
- _ZN7android7BBinder12setInheritRtEb;
- _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android7BBinder15isRequestingSidEv;
- _ZN7android7BBinder16setRequestingSidEb;
- _ZN7android7BBinder17getOrCreateExtrasEv;
- _ZN7android7BBinder21getMinSchedulerPolicyEv;
- _ZN7android7BBinder21setMinSchedulerPolicyEii;
- _ZN7android7BBinder23getMinSchedulerPriorityEv;
- _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinderC1Ev;
- _ZN7android7BBinderC2Ev;
- _ZN7android7BBinderD0Ev;
- _ZN7android7BBinderD1Ev;
- _ZN7android7BBinderD2Ev;
- _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
- _ZN7android7content2pm21IPackageManagerNative10descriptorE;
- _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm21IPackageManagerNative12default_implE;
- _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
- _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm21IPackageManagerNativeC2Ev;
- _ZN7android7content2pm21IPackageManagerNativeD0Ev;
- _ZN7android7content2pm21IPackageManagerNativeD1Ev;
- _ZN7android7content2pm21IPackageManagerNativeD2Ev;
- _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
- _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
- _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
- _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
- _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPl;
- _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
- _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
- _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
- _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver12default_implE;
- _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
- _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm22IPackageChangeObserverC2Ev;
- _ZN7android7content2pm22IPackageChangeObserverD0Ev;
- _ZN7android7content2pm22IPackageChangeObserverD1Ev;
- _ZN7android7content2pm22IPackageChangeObserverD2Ev;
- _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
- _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
- _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7HexDumpC1EPKvmm;
- _ZN7android7HexDumpC2EPKvmm;
- _ZN7android7IBinder11getDebugPidEPi;
- _ZN7android7IBinder11localBinderEv;
- _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
- _ZN7android7IBinder12remoteBinderEv;
- _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
- _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
- _ZN7android7IBinderC2Ev;
- _ZN7android7IBinderD0Ev;
- _ZN7android7IBinderD1Ev;
- _ZN7android7IBinderD2Ev;
- _ZN7android7IMemory10descriptorE;
- _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7IMemory12default_implE;
- _ZN7android7IMemory14getDefaultImplEv;
- _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android7IMemoryC2Ev;
- _ZN7android7IMemoryD0Ev;
- _ZN7android7IMemoryD1Ev;
- _ZN7android7IMemoryD2Ev;
- _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BnMemoryC2Ev;
- _ZN7android8BnMemoryD0Ev;
- _ZN7android8BnMemoryD1Ev;
- _ZN7android8BnMemoryD2Ev;
- _ZN7android8BpBinder10onFirstRefEv;
- _ZN7android8BpBinder10pingBinderEv;
- _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android8BpBinder12detachObjectEPKv;
- _ZN7android8BpBinder12remoteBinderEv;
- _ZN7android8BpBinder12sendObituaryEv;
- _ZN7android8BpBinder12sTrackingMapE;
- _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
- _ZN7android8BpBinder13ObjectManager4killEv;
- _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
- _ZN7android8BpBinder13ObjectManager6detachEPKv;
- _ZN7android8BpBinder13ObjectManagerC1Ev;
- _ZN7android8BpBinder13ObjectManagerC2Ev;
- _ZN7android8BpBinder13ObjectManagerD1Ev;
- _ZN7android8BpBinder13ObjectManagerD2Ev;
- _ZN7android8BpBinder13sTrackingLockE;
- _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
- _ZN7android8BpBinder14sLimitCallbackE;
- _ZN7android8BpBinder15onLastStrongRefEPKv;
- _ZN7android8BpBinder15sNumTrackedUidsE;
- _ZN7android8BpBinder16enableCountByUidEv;
- _ZN7android8BpBinder16setLimitCallbackEPFviE;
- _ZN7android8BpBinder17disableCountByUidEv;
- _ZN7android8BpBinder18sCountByUidEnabledE;
- _ZN7android8BpBinder19getBinderProxyCountEj;
- _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZN7android8BpBinder20setCountByUidEnabledEb;
- _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
- _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
- _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
- _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
- _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android8BpBinder6createEi;
- _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC1EONS0_9RpcHandleE;
- _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC2EONS0_9RpcHandleE;
- _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderD0Ev;
- _ZN7android8BpBinderD1Ev;
- _ZN7android8BpBinderD2Ev;
- _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryD0Ev;
- _ZN7android8BpMemoryD1Ev;
- _ZN7android8BpMemoryD2Ev;
- _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
- _ZN7android8internal9Stability11levelStringENS1_5LevelE;
- _ZN7android8internal9Stability13getLocalLevelEv;
- _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
- _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
- _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
- _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
- _ZN7android8internal9Stability8Category11debugStringEv;
- _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
- _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
- _ZN7android8RpcState11CommandDataC1Em;
- _ZN7android8RpcState11CommandDataC2Em;
- _ZN7android8RpcState12countBindersEv;
- _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
- _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
- _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPm;
- _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
- _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
- _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
- _ZN7android8RpcState4dumpEv;
- _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvm;
- _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvm;
- _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
- _ZN7android8RpcState9terminateEv;
- _ZN7android8RpcStateC1Ev;
- _ZN7android8RpcStateC2Ev;
- _ZN7android8RpcStateD1Ev;
- _ZN7android8RpcStateD2Ev;
- _ZN7android9BpRefBase10onFirstRefEv;
- _ZN7android9BpRefBase15onLastStrongRefEPKv;
- _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseD0Ev;
- _ZN7android9BpRefBaseD1Ev;
- _ZN7android9BpRefBaseD2Ev;
- _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCache10dump_heapsEv;
- _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCacheC1Ev;
- _ZN7android9HeapCacheC2Ev;
- _ZN7android9HeapCacheD0Ev;
- _ZN7android9HeapCacheD1Ev;
- _ZN7android9HeapCacheD2Ev;
- _ZN7android9hexStringEPKvm;
- _ZN7android9RpcServer12listSessionsEv;
- _ZN7android9RpcServer13getMaxThreadsEv;
- _ZN7android9RpcServer13getRootObjectEv;
- _ZN7android9RpcServer13releaseServerEv;
- _ZN7android9RpcServer13setMaxThreadsEm;
- _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android9RpcServer15setupInetServerEjPj;
- _ZN7android9RpcServer16setupVsockServerEj;
- _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
- _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
- _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
- _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
- _ZN7android9RpcServer21setupUnixDomainServerEPKc;
- _ZN7android9RpcServer24numUninitializedSessionsEv;
- _ZN7android9RpcServer4joinEv;
- _ZN7android9RpcServer4makeEv;
- _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
- _ZN7android9RpcServer9acceptOneEv;
- _ZN7android9RpcServer9hasServerEv;
- _ZN7android9RpcServerC1Ev;
- _ZN7android9RpcServerC2Ev;
- _ZN7android9RpcServerD0Ev;
- _ZN7android9RpcServerD1Ev;
- _ZN7android9RpcServerD2Ev;
- _ZN7android9SingletonINS_15PermissionCacheEE11getInstanceEv;
- _ZN7android9SingletonINS_15PermissionCacheEE11hasInstanceEv;
- _ZN7android9SingletonINS_15PermissionCacheEE5sLockE;
- _ZN7android9SingletonINS_15PermissionCacheEE9sInstanceE;
- _ZN7android9SingletonINS_15PermissionCacheEEC1Ev;
- _ZN7android9SingletonINS_15PermissionCacheEEC2Ev;
- _ZN7android9SingletonINS_15PermissionCacheEED1Ev;
- _ZN7android9SingletonINS_15PermissionCacheEED2Ev;
- _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
- _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
- _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsImEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
- _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
- _ZNK7android10MemoryBase9getMemoryEPlPm;
- _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
- _ZNK7android10RpcAddress15viewRawEmbeddedEv;
- _ZNK7android10RpcAddress6isZeroEv;
- _ZNK7android10RpcAddress8toStringEv;
- _ZNK7android10RpcAddressltERKS0_;
- _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
- _ZNK7android12BpMemoryHeap12assertMappedEv;
- _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
- _ZNK7android12BpMemoryHeap7getBaseEv;
- _ZNK7android12BpMemoryHeap7getSizeEv;
- _ZNK7android12BpMemoryHeap8getFlagsEv;
- _ZNK7android12BpMemoryHeap9getHeapIDEv;
- _ZNK7android12BpMemoryHeap9getOffsetEv;
- _ZNK7android12MemoryDealer4dumpEPKc;
- _ZNK7android12MemoryDealer4heapEv;
- _ZNK7android12MemoryDealer9allocatorEv;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_compareEPKvS5_;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE15do_move_forwardEPvPKvm;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE16do_move_backwardEPvPKvm;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE7do_copyEPvPKvm;
- _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE8do_splatEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_m;
- _ZNK7android12SortedVectorINS_8String16EE10do_compareEPKvS4_;
- _ZNK7android12SortedVectorINS_8String16EE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_8String16EE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_8String16EE15do_move_forwardEPvPKvm;
- _ZNK7android12SortedVectorINS_8String16EE16do_move_backwardEPvPKvm;
- _ZNK7android12SortedVectorINS_8String16EE7do_copyEPvPKvm;
- _ZNK7android12SortedVectorINS_8String16EE8do_splatEPvPKvm;
- _ZNK7android14IPCThreadState13getCallingPidEv;
- _ZNK7android14IPCThreadState13getCallingSidEv;
- _ZNK7android14IPCThreadState13getCallingUidEv;
- _ZNK7android14IPCThreadState18getCallRestrictionEv;
- _ZNK7android14IPCThreadState19getStrictModePolicyEv;
- _ZNK7android14IPCThreadState22getServingStackPointerEv;
- _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
- _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
- _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
- _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
- _ZNK7android14MemoryHeapBase7getBaseEv;
- _ZNK7android14MemoryHeapBase7getSizeEv;
- _ZNK7android14MemoryHeapBase8getFlagsEv;
- _ZNK7android14MemoryHeapBase9getDeviceEv;
- _ZNK7android14MemoryHeapBase9getHeapIDEv;
- _ZNK7android14MemoryHeapBase9getOffsetEv;
- _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
- _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android15PermissionCache5checkEPbRKNS_8String16Ej;
- _ZNK7android18BufferedTextOutput9getBufferEv;
- _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
- _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
- _ZNK7android21IPermissionController22getInterfaceDescriptorEv;
- _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
- _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
- _ZNK7android22SimpleBestFitAllocator4sizeEv;
- _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
- _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
- _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
- _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
- _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
- _ZNK7android2os17PersistableBundle10getIntKeysEv;
- _ZNK7android2os17PersistableBundle11getLongKeysEv;
- _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
- _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIlNS5_9allocatorIlEEEE;
- _ZNK7android2os17PersistableBundle13getStringKeysEv;
- _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
- _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
- _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
- _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
- _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
- _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
- _ZNK7android2os17PersistableBundle4sizeEv;
- _ZNK7android2os17PersistableBundle5emptyEv;
- _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
- _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPl;
- _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
- _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
- _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status9toString8Ev;
- _ZNK7android6Parcel10errorCheckEv;
- _ZNK7android6Parcel10ipcObjectsEv;
- _ZNK7android6Parcel10readDoubleEPd;
- _ZNK7android6Parcel10readDoubleEv;
- _ZNK7android6Parcel10readObjectEb;
- _ZNK7android6Parcel10readUint32EPj;
- _ZNK7android6Parcel10readUint32Ev;
- _ZNK7android6Parcel10readUint64EPm;
- _ZNK7android6Parcel10readUint64Ev;
- _ZNK7android6Parcel10scanForFdsEv;
- _ZNK7android6Parcel11ipcDataSizeEv;
- _ZNK7android6Parcel11readCStringEv;
- _ZNK7android6Parcel11readInplaceEm;
- _ZNK7android6Parcel11readPointerEPm;
- _ZNK7android6Parcel11readPointerEv;
- _ZNK7android6Parcel11readString8EPNS_7String8E;
- _ZNK7android6Parcel11readString8Ev;
- _ZNK7android6Parcel12dataCapacityEv;
- _ZNK7android6Parcel12dataPositionEv;
- _ZNK7android6Parcel12objectsCountEv;
- _ZNK7android6Parcel12readString16EPNS_8String16E;
- _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
- _ZNK7android6Parcel12readString16Ev;
- _ZNK7android6Parcel13markSensitiveEv;
- _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
- _ZNK7android6Parcel15ipcObjectsCountEv;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIlNS1_9allocatorIlEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
- _ZNK7android6Parcel15setDataPositionEm;
- _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16enforceInterfaceEPKDsmPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZNK7android6Parcel16readNativeHandleEv;
- _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16readStrongBinderEv;
- _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorImNS1_9allocatorImEEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
- _ZNK7android6Parcel16validateReadDataEm;
- _ZNK7android6Parcel17getBlobAshmemSizeEv;
- _ZNK7android6Parcel17getOpenAshmemSizeEv;
- _ZNK7android6Parcel17readExceptionCodeEv;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZNK7android6Parcel18hasFileDescriptorsEv;
- _ZNK7android6Parcel18readFileDescriptorEv;
- _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZNK7android6Parcel18readString8InplaceEPm;
- _ZNK7android6Parcel19readString16InplaceEPm;
- _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZNK7android6Parcel24readCallingWorkSourceUidEv;
- _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel24readParcelFileDescriptorEv;
- _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
- _ZNK7android6Parcel4dataEv;
- _ZNK7android6Parcel4readEPvm;
- _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
- _ZNK7android6Parcel5printERNS_10TextOutputEj;
- _ZNK7android6Parcel7ipcDataEv;
- _ZNK7android6Parcel8allowFdsEv;
- _ZNK7android6Parcel8dataSizeEv;
- _ZNK7android6Parcel8isForRpcEv;
- _ZNK7android6Parcel8readBlobEmPNS0_12ReadableBlobE;
- _ZNK7android6Parcel8readBoolEPb;
- _ZNK7android6Parcel8readBoolEv;
- _ZNK7android6Parcel8readByteEPa;
- _ZNK7android6Parcel8readByteEv;
- _ZNK7android6Parcel8readCharEPDs;
- _ZNK7android6Parcel8readCharEv;
- _ZNK7android6Parcel9dataAvailEv;
- _ZNK7android6Parcel9readFloatEPf;
- _ZNK7android6Parcel9readFloatEv;
- _ZNK7android6Parcel9readInt32EPi;
- _ZNK7android6Parcel9readInt32Ev;
- _ZNK7android6Parcel9readInt64EPl;
- _ZNK7android6Parcel9readInt64Ev;
- _ZNK7android6VectorIiE10do_destroyEPvm;
- _ZNK7android6VectorIiE12do_constructEPvm;
- _ZNK7android6VectorIiE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIiE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIiE7do_copyEPvPKvm;
- _ZNK7android6VectorIiE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_8String16EE10do_destroyEPvm;
- _ZNK7android6VectorINS_8String16EE12do_constructEPvm;
- _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvm;
- _ZNK7android7BBinder10findObjectEPKv;
- _ZNK7android7BBinder13isBinderAliveEv;
- _ZNK7android7BBinder22getInterfaceDescriptorEv;
- _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
- _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
- _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
- _ZNK7android7IBinder13checkSubclassEPKv;
- _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEl;
- _ZNK7android7IMemory15unsecurePointerEv;
- _ZNK7android7IMemory22getInterfaceDescriptorEv;
- _ZNK7android7IMemory4sizeEv;
- _ZNK7android7IMemory6offsetEv;
- _ZNK7android7IMemory7pointerEv;
- _ZNK7android8BpBinder10findObjectEPKv;
- _ZNK7android8BpBinder10rpcAddressEv;
- _ZNK7android8BpBinder10rpcSessionEv;
- _ZNK7android8BpBinder11isRpcBinderEv;
- _ZNK7android8BpBinder12binderHandleEv;
- _ZNK7android8BpBinder13isBinderAliveEv;
- _ZNK7android8BpBinder13ObjectManager4findEPKv;
- _ZNK7android8BpBinder18isDescriptorCachedEv;
- _ZNK7android8BpBinder22getInterfaceDescriptorEv;
- _ZNK7android8BpMemory9getMemoryEPlPm;
- _ZTCN7android10AllocationE0_NS_10IInterfaceE;
- _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
- _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10AllocationE0_NS_7IMemoryE;
- _ZTCN7android10AllocationE0_NS_8BnMemoryE;
- _ZTCN7android10AllocationE8_NS_7BBinderE;
- _ZTCN7android10AllocationE8_NS_7IBinderE;
- _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
- _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
- _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
- _ZTCN7android10MemoryBaseE8_NS_7BBinderE;
- _ZTCN7android10MemoryBaseE8_NS_7IBinderE;
- _ZTCN7android10PoolThreadE0_NS_6ThreadE;
- _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BnMemoryHeapE8_NS_7BBinderE;
- _ZTCN7android12BnMemoryHeapE8_NS_7IBinderE;
- _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BpMemoryHeapE8_NS_9BpRefBaseE;
- _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE64_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE64_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android14MemoryHeapBaseE64_NS_11IMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE64_NS_12BnMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE72_NS_7BBinderE;
- _ZTCN7android14MemoryHeapBaseE72_NS_7IBinderE;
- _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BnShellCallbackE8_NS_7BBinderE;
- _ZTCN7android15BnShellCallbackE8_NS_7IBinderE;
- _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BpShellCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BnResultReceiverE8_NS_7BBinderE;
- _ZTCN7android16BnResultReceiverE8_NS_7IBinderE;
- _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BpResultReceiverE8_NS_9BpRefBaseE;
- _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
- _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
- _ZTCN7android21IPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BnPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BnPermissionControllerE0_NS_11BnInterfaceINS_21IPermissionControllerEEE;
- _ZTCN7android22BnPermissionControllerE0_NS_21IPermissionControllerE;
- _ZTCN7android22BnPermissionControllerE8_NS_7BBinderE;
- _ZTCN7android22BnPermissionControllerE8_NS_7IBinderE;
- _ZTCN7android22BpPermissionControllerE0_NS_10IInterfaceE;
- _ZTCN7android22BpPermissionControllerE0_NS_11BpInterfaceINS_21IPermissionControllerEEE;
- _ZTCN7android22BpPermissionControllerE0_NS_21IPermissionControllerE;
- _ZTCN7android22BpPermissionControllerE8_NS_9BpRefBaseE;
- _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BnClientCallbackE8_NS_7BBinderE;
- _ZTCN7android2os16BnClientCallbackE8_NS_7IBinderE;
- _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BnServiceManagerE8_NS_7BBinderE;
- _ZTCN7android2os16BnServiceManagerE8_NS_7IBinderE;
- _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BpClientCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BpServiceManagerE8_NS_9BpRefBaseE;
- _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BnServiceCallbackE8_NS_7BBinderE;
- _ZTCN7android2os17BnServiceCallbackE8_NS_7IBinderE;
- _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BpServiceCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android7BBinderE0_NS_7IBinderE;
- _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7BBinderE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7IBinderE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE8_NS_9BpRefBaseE;
- _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7BBinderE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7IBinderE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE8_NS_9BpRefBaseE;
- _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BnMemoryE8_NS_7BBinderE;
- _ZTCN7android8BnMemoryE8_NS_7IBinderE;
- _ZTCN7android8BpBinderE0_NS_7IBinderE;
- _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BpMemoryE8_NS_9BpRefBaseE;
- _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE;
- _ZThn8_N7android10AllocationD0Ev;
- _ZThn8_N7android10AllocationD1Ev;
- _ZThn8_N7android10MemoryBaseD0Ev;
- _ZThn8_N7android10MemoryBaseD1Ev;
- _ZThn8_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android12BnMemoryHeapD0Ev;
- _ZThn8_N7android12BnMemoryHeapD1Ev;
- _ZThn8_N7android12BpMemoryHeapD0Ev;
- _ZThn8_N7android12BpMemoryHeapD1Ev;
- _ZThn8_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn8_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn8_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android8BnMemoryD0Ev;
- _ZThn8_N7android8BnMemoryD1Ev;
- _ZThn8_N7android8BpMemoryD0Ev;
- _ZThn8_N7android8BpMemoryD1Ev;
- _ZTTN7android10AllocationE;
- _ZTTN7android10IInterfaceE;
- _ZTTN7android10MemoryBaseE;
- _ZTTN7android10PoolThreadE;
- _ZTTN7android10RpcSessionE;
- _ZTTN7android11IMemoryHeapE;
- _ZTTN7android12BnMemoryHeapE;
- _ZTTN7android12BpMemoryHeapE;
- _ZTTN7android12ProcessStateE;
- _ZTTN7android14IShellCallbackE;
- _ZTTN7android14MemoryHeapBaseE;
- _ZTTN7android15BnShellCallbackE;
- _ZTTN7android15BpShellCallbackE;
- _ZTTN7android15IResultReceiverE;
- _ZTTN7android15IServiceManagerE;
- _ZTTN7android16BnResultReceiverE;
- _ZTTN7android16BpResultReceiverE;
- _ZTTN7android18ServiceManagerShimE;
- _ZTTN7android21IPermissionControllerE;
- _ZTTN7android22BnPermissionControllerE;
- _ZTTN7android22BpPermissionControllerE;
- _ZTTN7android2os15IClientCallbackE;
- _ZTTN7android2os15IServiceManagerE;
- _ZTTN7android2os16BnClientCallbackE;
- _ZTTN7android2os16BnServiceManagerE;
- _ZTTN7android2os16BpClientCallbackE;
- _ZTTN7android2os16BpServiceManagerE;
- _ZTTN7android2os16IServiceCallbackE;
- _ZTTN7android2os17BnServiceCallbackE;
- _ZTTN7android2os17BpServiceCallbackE;
- _ZTTN7android7BBinderE;
- _ZTTN7android7content2pm21IPackageManagerNativeE;
- _ZTTN7android7content2pm22BnPackageManagerNativeE;
- _ZTTN7android7content2pm22BpPackageManagerNativeE;
- _ZTTN7android7content2pm22IPackageChangeObserverE;
- _ZTTN7android7content2pm23BnPackageChangeObserverE;
- _ZTTN7android7content2pm23BpPackageChangeObserverE;
- _ZTTN7android7IBinderE;
- _ZTTN7android7IMemoryE;
- _ZTTN7android8BnMemoryE;
- _ZTTN7android8BpBinderE;
- _ZTTN7android8BpMemoryE;
- _ZTTN7android9BpRefBaseE;
- _ZTTN7android9HeapCacheE;
- _ZTTN7android9RpcServerE;
- _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
- _ZTv0_n24_N7android10AllocationD0Ev;
- _ZTv0_n24_N7android10AllocationD1Ev;
- _ZTv0_n24_N7android10IInterfaceD0Ev;
- _ZTv0_n24_N7android10IInterfaceD1Ev;
- _ZTv0_n24_N7android10MemoryBaseD0Ev;
- _ZTv0_n24_N7android10MemoryBaseD1Ev;
- _ZTv0_n24_N7android10RpcSessionD0Ev;
- _ZTv0_n24_N7android10RpcSessionD1Ev;
- _ZTv0_n24_N7android11IMemoryHeapD0Ev;
- _ZTv0_n24_N7android11IMemoryHeapD1Ev;
- _ZTv0_n24_N7android12BnMemoryHeapD0Ev;
- _ZTv0_n24_N7android12BnMemoryHeapD1Ev;
- _ZTv0_n24_N7android12BpMemoryHeapD0Ev;
- _ZTv0_n24_N7android12BpMemoryHeapD1Ev;
- _ZTv0_n24_N7android12ProcessStateD0Ev;
- _ZTv0_n24_N7android12ProcessStateD1Ev;
- _ZTv0_n24_N7android14IShellCallbackD0Ev;
- _ZTv0_n24_N7android14IShellCallbackD1Ev;
- _ZTv0_n24_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n24_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n24_N7android15IResultReceiverD0Ev;
- _ZTv0_n24_N7android15IResultReceiverD1Ev;
- _ZTv0_n24_N7android15IServiceManagerD0Ev;
- _ZTv0_n24_N7android15IServiceManagerD1Ev;
- _ZTv0_n24_N7android21IPermissionControllerD0Ev;
- _ZTv0_n24_N7android21IPermissionControllerD1Ev;
- _ZTv0_n24_N7android2os15IClientCallbackD0Ev;
- _ZTv0_n24_N7android2os15IClientCallbackD1Ev;
- _ZTv0_n24_N7android2os15IServiceManagerD0Ev;
- _ZTv0_n24_N7android2os15IServiceManagerD1Ev;
- _ZTv0_n24_N7android2os16IServiceCallbackD0Ev;
- _ZTv0_n24_N7android2os16IServiceCallbackD1Ev;
- _ZTv0_n24_N7android7BBinderD0Ev;
- _ZTv0_n24_N7android7BBinderD1Ev;
- _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD0Ev;
- _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD1Ev;
- _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD0Ev;
- _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD1Ev;
- _ZTv0_n24_N7android7IBinderD0Ev;
- _ZTv0_n24_N7android7IBinderD1Ev;
- _ZTv0_n24_N7android7IMemoryD0Ev;
- _ZTv0_n24_N7android7IMemoryD1Ev;
- _ZTv0_n24_N7android8BnMemoryD0Ev;
- _ZTv0_n24_N7android8BnMemoryD1Ev;
- _ZTv0_n24_N7android8BpBinderD0Ev;
- _ZTv0_n24_N7android8BpBinderD1Ev;
- _ZTv0_n24_N7android8BpMemoryD0Ev;
- _ZTv0_n24_N7android8BpMemoryD1Ev;
- _ZTv0_n24_N7android9BpRefBaseD0Ev;
- _ZTv0_n24_N7android9BpRefBaseD1Ev;
- _ZTv0_n24_N7android9HeapCacheD0Ev;
- _ZTv0_n24_N7android9HeapCacheD1Ev;
- _ZTv0_n24_N7android9RpcServerD0Ev;
- _ZTv0_n24_N7android9RpcServerD1Ev;
- _ZTv0_n32_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n32_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n32_N7android8BpBinder10onFirstRefEv;
- _ZTv0_n32_N7android9BpRefBase10onFirstRefEv;
- _ZTv0_n40_N7android8BpBinder15onLastStrongRefEPKv;
- _ZTv0_n40_N7android9BpRefBase15onLastStrongRefEPKv;
- _ZTv0_n48_N7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZTv0_n48_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZTv0_n56_NK7android14MemoryHeapBase9getHeapIDEv;
- _ZTv0_n64_NK7android14MemoryHeapBase7getBaseEv;
- _ZTv0_n72_NK7android14MemoryHeapBase7getSizeEv;
- _ZTv0_n80_NK7android14MemoryHeapBase8getFlagsEv;
- _ZTv0_n88_NK7android14MemoryHeapBase9getOffsetEv;
- _ZTVN7android10AllocationE;
- _ZTVN7android10IInterfaceE;
- _ZTVN7android10MemoryBaseE;
- _ZTVN7android10PoolThreadE;
- _ZTVN7android10RpcSession13RpcConnectionE;
- _ZTVN7android10RpcSessionE;
- _ZTVN7android10TextOutputE;
- _ZTVN7android11IMemoryHeapE;
- _ZTVN7android12BnMemoryHeapE;
- _ZTVN7android12BpMemoryHeapE;
- _ZTVN7android12FdTextOutputE;
- _ZTVN7android12MemoryDealerE;
- _ZTVN7android12ProcessStateE;
- _ZTVN7android12SortedVectorINS_15PermissionCache5EntryEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
- _ZTVN7android12SortedVectorINS_8String16EEE;
- _ZTVN7android13LogTextOutputE;
- _ZTVN7android14IShellCallbackE;
- _ZTVN7android14MemoryHeapBaseE;
- _ZTVN7android15BnShellCallbackE;
- _ZTVN7android15BpShellCallbackE;
- _ZTVN7android15IResultReceiverE;
- _ZTVN7android15IServiceManagerE;
- _ZTVN7android16BnResultReceiverE;
- _ZTVN7android16BpResultReceiverE;
- _ZTVN7android17InetSocketAddressE;
- _ZTVN7android17UnixSocketAddressE;
- _ZTVN7android18BufferedTextOutput11BufferStateE;
- _ZTVN7android18BufferedTextOutputE;
- _ZTVN7android18ServiceManagerShimE;
- _ZTVN7android18VsockSocketAddressE;
- _ZTVN7android21IPermissionControllerE;
- _ZTVN7android22BnPermissionControllerE;
- _ZTVN7android22BpPermissionControllerE;
- _ZTVN7android2os15IClientCallbackE;
- _ZTVN7android2os15IServiceManagerE;
- _ZTVN7android2os16BnClientCallbackE;
- _ZTVN7android2os16BnServiceManagerE;
- _ZTVN7android2os16BpClientCallbackE;
- _ZTVN7android2os16BpServiceManagerE;
- _ZTVN7android2os16IServiceCallbackE;
- _ZTVN7android2os16ParcelableHolderE;
- _ZTVN7android2os16ServiceDebugInfoE;
- _ZTVN7android2os17BnServiceCallbackE;
- _ZTVN7android2os17BpServiceCallbackE;
- _ZTVN7android2os17PersistableBundleE;
- _ZTVN7android2os20ParcelFileDescriptorE;
- _ZTVN7android6VectorIiEE;
- _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
- _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
- _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
- _ZTVN7android6VectorINS_8String16EEE;
- _ZTVN7android6VectorIPNS_7BBinderEEE;
- _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
- _ZTVN7android6VectorIPNS_7RefBaseEEE;
- _ZTVN7android7BBinderE;
- _ZTVN7android7content2pm18PackageChangeEventE;
- _ZTVN7android7content2pm21IPackageManagerNativeE;
- _ZTVN7android7content2pm22BnPackageManagerNativeE;
- _ZTVN7android7content2pm22BpPackageManagerNativeE;
- _ZTVN7android7content2pm22IPackageChangeObserverE;
- _ZTVN7android7content2pm23BnPackageChangeObserverE;
- _ZTVN7android7content2pm23BpPackageChangeObserverE;
- _ZTVN7android7IBinderE;
- _ZTVN7android7IMemoryE;
- _ZTVN7android8BnMemoryE;
- _ZTVN7android8BpBinderE;
- _ZTVN7android8BpMemoryE;
- _ZTVN7android9BpRefBaseE;
- _ZTVN7android9HeapCacheE;
- _ZTVN7android9RpcServerE;
- _ZTvn8_n32_N7android14MemoryHeapBaseD0Ev;
- _ZTvn8_n32_N7android14MemoryHeapBaseD1Ev;
- local:
- *;
-};
diff --git a/libs/binder/libbinder.arm64.vendor.map b/libs/binder/libbinder.arm64.vendor.map
deleted file mode 100644
index df6aa66..0000000
--- a/libs/binder/libbinder.arm64.vendor.map
+++ /dev/null
@@ -1,1320 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
- global:
- getBinderKernelReferences;
- kDefaultDriver;
- _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
- _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
- _ZN7android10AllocationD0Ev;
- _ZN7android10AllocationD1Ev;
- _ZN7android10AllocationD2Ev;
- _ZN7android10IInterface8asBinderEPKS0_;
- _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
- _ZN7android10IInterfaceC2Ev;
- _ZN7android10IInterfaceD0Ev;
- _ZN7android10IInterfaceD1Ev;
- _ZN7android10IInterfaceD2Ev;
- _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElm;
- _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEElm;
- _ZN7android10MemoryBaseD0Ev;
- _ZN7android10MemoryBaseD1Ev;
- _ZN7android10MemoryBaseD2Ev;
- _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
- _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
- _ZN7android10RpcAddress4zeroEv;
- _ZN7android10RpcAddress6uniqueEv;
- _ZN7android10RpcAddressC1Ev;
- _ZN7android10RpcAddressC2Ev;
- _ZN7android10RpcAddressD1Ev;
- _ZN7android10RpcAddressD2Ev;
- _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
- _ZN7android10RpcSession13getRootObjectEv;
- _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
- _ZN7android10RpcSession15setupInetClientEPKcj;
- _ZN7android10RpcSession15terminateLockedEv;
- _ZN7android10RpcSession16setupVsockClientEjj;
- _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
- _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEm;
- _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
- _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
- _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
- _ZN7android10RpcSession19getRemoteMaxThreadsEPm;
- _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
- _ZN7android10RpcSession21setupUnixDomainClientEPKc;
- _ZN7android10RpcSession22addNullDebuggingClientEv;
- _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
- _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android10RpcSession4makeEv;
- _ZN7android10RpcSession6readIdEv;
- _ZN7android10RpcSession6serverEv;
- _ZN7android10RpcSession7preJoinENSt3__16threadE;
- _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
- _ZN7android10RpcSessionC1Ev;
- _ZN7android10RpcSessionC2Ev;
- _ZN7android10RpcSessionD0Ev;
- _ZN7android10RpcSessionD1Ev;
- _ZN7android10RpcSessionD2Ev;
- _ZN7android10TextOutputC2Ev;
- _ZN7android10TextOutputD0Ev;
- _ZN7android10TextOutputD1Ev;
- _ZN7android10TextOutputD2Ev;
- _ZN7android10zeroMemoryEPhm;
- _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
- _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
- _ZN7android11IMemoryHeap10descriptorE;
- _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android11IMemoryHeap12default_implE;
- _ZN7android11IMemoryHeap14getDefaultImplEv;
- _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android11IMemoryHeapC2Ev;
- _ZN7android11IMemoryHeapD0Ev;
- _ZN7android11IMemoryHeapD1Ev;
- _ZN7android11IMemoryHeapD2Ev;
- _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android12BnMemoryHeapC2Ev;
- _ZN7android12BnMemoryHeapD0Ev;
- _ZN7android12BnMemoryHeapD1Ev;
- _ZN7android12BnMemoryHeapD2Ev;
- _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android12BpMemoryHeapD0Ev;
- _ZN7android12BpMemoryHeapD1Ev;
- _ZN7android12BpMemoryHeapD2Ev;
- _ZN7android12gTextBuffersE;
- _ZN7android12MemoryDealer10deallocateEm;
- _ZN7android12MemoryDealer22getAllocationAlignmentEv;
- _ZN7android12MemoryDealer8allocateEm;
- _ZN7android12MemoryDealerC1EmPKcj;
- _ZN7android12MemoryDealerC2EmPKcj;
- _ZN7android12MemoryDealerD0Ev;
- _ZN7android12MemoryDealerD1Ev;
- _ZN7android12MemoryDealerD2Ev;
- _ZN7android12printHexDataEiPKvmmimbPFvPvPKcES2_;
- _ZN7android12ProcessState10selfOrNullEv;
- _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
- _ZN7android12ProcessState13getDriverNameEv;
- _ZN7android12ProcessState14initWithDriverEPKc;
- _ZN7android12ProcessState15startThreadPoolEv;
- _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android12ProcessState17spawnPooledThreadEb;
- _ZN7android12ProcessState18giveThreadPoolNameEv;
- _ZN7android12ProcessState18lookupHandleLockedEi;
- _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
- _ZN7android12ProcessState19getKernelReferencesEmPm;
- _ZN7android12ProcessState20becomeContextManagerEv;
- _ZN7android12ProcessState20makeBinderThreadNameEv;
- _ZN7android12ProcessState23getStrongProxyForHandleEi;
- _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
- _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
- _ZN7android12ProcessState27setThreadPoolMaxThreadCountEm;
- _ZN7android12ProcessState4initEPKcb;
- _ZN7android12ProcessState4selfEv;
- _ZN7android12ProcessStateC1EPKc;
- _ZN7android12ProcessStateC2EPKc;
- _ZN7android12ProcessStateD0Ev;
- _ZN7android12ProcessStateD1Ev;
- _ZN7android12ProcessStateD2Ev;
- _ZN7android13printTypeCodeEjPFvPvPKcES0_;
- _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhmPKym;
- _ZN7android14IPCThreadState10selfOrNullEv;
- _ZN7android14IPCThreadState11clearCallerEv;
- _ZN7android14IPCThreadState11stopProcessEb;
- _ZN7android14IPCThreadState12setupPollingEPi;
- _ZN7android14IPCThreadState13decWeakHandleEi;
- _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
- _ZN7android14IPCThreadState13flushCommandsEv;
- _ZN7android14IPCThreadState13flushIfNeededEv;
- _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState14clearLastErrorEv;
- _ZN7android14IPCThreadState14executeCommandEi;
- _ZN7android14IPCThreadState14joinThreadPoolEb;
- _ZN7android14IPCThreadState14talkWithDriverEb;
- _ZN7android14IPCThreadState15decStrongHandleEi;
- _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
- _ZN7android14IPCThreadState16threadDestructorEPv;
- _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
- _ZN7android14IPCThreadState19setStrictModePolicyEi;
- _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
- _ZN7android14IPCThreadState20clearCallingIdentityEv;
- _ZN7android14IPCThreadState20getAndExecuteCommandEv;
- _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
- _ZN7android14IPCThreadState20handlePolledCommandsEv;
- _ZN7android14IPCThreadState20processPendingDerefsEv;
- _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
- _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
- _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
- _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState22processPostWriteDerefsEv;
- _ZN7android14IPCThreadState22restoreCallingIdentityEl;
- _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
- _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
- _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
- _ZN7android14IPCThreadState24restoreCallingWorkSourceEl;
- _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
- _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
- _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
- _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
- _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
- _ZN7android14IPCThreadState4selfEv;
- _ZN7android14IPCThreadState6freezeEibj;
- _ZN7android14IPCThreadState7processEv;
- _ZN7android14IPCThreadState8shutdownEv;
- _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
- _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
- _ZN7android14IPCThreadStateC1Ev;
- _ZN7android14IPCThreadStateC2Ev;
- _ZN7android14IPCThreadStateD1Ev;
- _ZN7android14IPCThreadStateD2Ev;
- _ZN7android14IShellCallback10descriptorE;
- _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android14IShellCallback12default_implE;
- _ZN7android14IShellCallback14getDefaultImplEv;
- _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android14IShellCallbackC2Ev;
- _ZN7android14IShellCallbackD0Ev;
- _ZN7android14IShellCallbackD1Ev;
- _ZN7android14IShellCallbackD2Ev;
- _ZN7android14MemoryHeapBase4initEiPvmiPKc;
- _ZN7android14MemoryHeapBase5mapfdEibml;
- _ZN7android14MemoryHeapBase7disposeEv;
- _ZN7android14MemoryHeapBaseC1Eimjl;
- _ZN7android14MemoryHeapBaseC1EmjPKc;
- _ZN7android14MemoryHeapBaseC1EPKcmj;
- _ZN7android14MemoryHeapBaseC1Ev;
- _ZN7android14MemoryHeapBaseC2Eimjl;
- _ZN7android14MemoryHeapBaseC2EmjPKc;
- _ZN7android14MemoryHeapBaseC2EPKcmj;
- _ZN7android14MemoryHeapBaseC2Ev;
- _ZN7android14MemoryHeapBaseD0Ev;
- _ZN7android14MemoryHeapBaseD1Ev;
- _ZN7android14MemoryHeapBaseD2Ev;
- _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android15IResultReceiver10descriptorE;
- _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android15IResultReceiver12default_implE;
- _ZN7android15IResultReceiver14getDefaultImplEv;
- _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android15IResultReceiverC2Ev;
- _ZN7android15IResultReceiverD0Ev;
- _ZN7android15IResultReceiverD1Ev;
- _ZN7android15IResultReceiverD2Ev;
- _ZN7android15IServiceManagerC2Ev;
- _ZN7android15IServiceManagerD0Ev;
- _ZN7android15IServiceManagerD1Ev;
- _ZN7android15IServiceManagerD2Ev;
- _ZN7android15stringForIndentEi;
- _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android18BufferedTextOutput10moveIndentEi;
- _ZN7android18BufferedTextOutput10pushBundleEv;
- _ZN7android18BufferedTextOutput5printEPKcm;
- _ZN7android18BufferedTextOutput9popBundleEv;
- _ZN7android18BufferedTextOutputC2Ej;
- _ZN7android18BufferedTextOutputD0Ev;
- _ZN7android18BufferedTextOutputD1Ev;
- _ZN7android18BufferedTextOutputD2Ev;
- _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
- _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
- _ZN7android18ServiceManagerShim12listServicesEi;
- _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
- _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
- _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
- _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
- _ZN7android18the_context_objectE;
- _ZN7android21defaultServiceManagerEv;
- _ZN7android22SimpleBestFitAllocator10deallocateEm;
- _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
- _ZN7android22SimpleBestFitAllocator5allocEmj;
- _ZN7android22SimpleBestFitAllocator7deallocEm;
- _ZN7android22SimpleBestFitAllocator8allocateEmj;
- _ZN7android22SimpleBestFitAllocatorC1Em;
- _ZN7android22SimpleBestFitAllocatorC2Em;
- _ZN7android22SimpleBestFitAllocatorD1Ev;
- _ZN7android22SimpleBestFitAllocatorD2Ev;
- _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
- _ZN7android2os15IClientCallback10descriptorE;
- _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IClientCallback12default_implE;
- _ZN7android2os15IClientCallback14getDefaultImplEv;
- _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IClientCallbackC2Ev;
- _ZN7android2os15IClientCallbackD0Ev;
- _ZN7android2os15IClientCallbackD1Ev;
- _ZN7android2os15IClientCallbackD2Ev;
- _ZN7android2os15IServiceManager10descriptorE;
- _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os15IServiceManager12default_implE;
- _ZN7android2os15IServiceManager14getDefaultImplEv;
- _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os15IServiceManagerC2Ev;
- _ZN7android2os15IServiceManagerD0Ev;
- _ZN7android2os15IServiceManagerD1Ev;
- _ZN7android2os15IServiceManagerD2Ev;
- _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnClientCallbackC2Ev;
- _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os16BnServiceManagerC2Ev;
- _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
- _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
- _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
- _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
- _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
- _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
- _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
- _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
- _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
- _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback10descriptorE;
- _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android2os16IServiceCallback12default_implE;
- _ZN7android2os16IServiceCallback14getDefaultImplEv;
- _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
- _ZN7android2os16IServiceCallbackC2Ev;
- _ZN7android2os16IServiceCallbackD0Ev;
- _ZN7android2os16IServiceCallbackD1Ev;
- _ZN7android2os16IServiceCallbackD2Ev;
- _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZN7android2os17BnServiceCallbackC2Ev;
- _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
- _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIlNS5_9allocatorIlEEEE;
- _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEm;
- _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
- _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
- _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
- _ZN7android2os17PersistableBundle7putLongERKNS_8String16El;
- _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
- _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
- _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
- _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC1Ev;
- _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
- _ZN7android2os20ParcelFileDescriptorC2Ev;
- _ZN7android2os20ParcelFileDescriptorD0Ev;
- _ZN7android2os20ParcelFileDescriptorD1Ev;
- _ZN7android2os20ParcelFileDescriptorD2Ev;
- _ZN7android4aerrE;
- _ZN7android4alogE;
- _ZN7android4aoutE;
- _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
- _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
- _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
- _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
- _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
- _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder20LazyServiceRegistrarC1Ev;
- _ZN7android6binder20LazyServiceRegistrarC2Ev;
- _ZN7android6binder6Status11fromStatusTEi;
- _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
- _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
- _ZN7android6binder6Status14setFromStatusTEi;
- _ZN7android6binder6Status17exceptionToStringEi;
- _ZN7android6binder6Status17fromExceptionCodeEi;
- _ZN7android6binder6Status17fromExceptionCodeEiPKc;
- _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
- _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status24fromServiceSpecificErrorEi;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
- _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
- _ZN7android6binder6Status2okEv;
- _ZN7android6binder6StatusC1Eii;
- _ZN7android6binder6StatusC1EiiRKNS_7String8E;
- _ZN7android6binder6StatusC2Eii;
- _ZN7android6binder6StatusC2EiiRKNS_7String8E;
- _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
- _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
- _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
- _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
- _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
- _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
- _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
- _ZN7android6Parcel10appendFromEPKS0_mm;
- _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
- _ZN7android6Parcel10writeFloatEf;
- _ZN7android6Parcel10writeInt32Ei;
- _ZN7android6Parcel10writeInt64El;
- _ZN7android6Parcel11compareDataERKS0_;
- _ZN7android6Parcel11finishWriteEm;
- _ZN7android6Parcel11setDataSizeEm;
- _ZN7android6Parcel11writeDoubleEd;
- _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
- _ZN7android6Parcel11writeUint32Ej;
- _ZN7android6Parcel11writeUint64Em;
- _ZN7android6Parcel12pushAllowFdsEb;
- _ZN7android6Parcel12restartWriteEm;
- _ZN7android6Parcel12writeCStringEPKc;
- _ZN7android6Parcel12writeInplaceEm;
- _ZN7android6Parcel12writePointerEm;
- _ZN7android6Parcel12writeString8EPKcm;
- _ZN7android6Parcel12writeString8ERKNS_7String8E;
- _ZN7android6Parcel13continueWriteEm;
- _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel13writeString16EPKDsm;
- _ZN7android6Parcel13writeString16ERKNS_8String16E;
- _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
- _ZN7android6Parcel13writeUnpaddedEPKvm;
- _ZN7android6Parcel14acquireObjectsEv;
- _ZN7android6Parcel14freeDataNoInitEv;
- _ZN7android6Parcel14releaseObjectsEv;
- _ZN7android6Parcel14writeByteArrayEmPKh;
- _ZN7android6Parcel15restoreAllowFdsEb;
- _ZN7android6Parcel15setDataCapacityEm;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZN7android6Parcel15writeInt32ArrayEmPKi;
- _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIlNS1_9allocatorIlEEEE;
- _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
- _ZN7android6Parcel16writeNoExceptionEv;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
- _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorImNS1_9allocatorImEEEE;
- _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
- _ZN7android6Parcel18getGlobalAllocSizeEv;
- _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
- _ZN7android6Parcel19getGlobalAllocCountEv;
- _ZN7android6Parcel19ipcSetDataReferenceEPKhmPKymPFvPS0_S2_mS4_mE;
- _ZN7android6Parcel19writeFileDescriptorEib;
- _ZN7android6Parcel19writeInterfaceTokenEPKDsm;
- _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
- _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZN7android6Parcel20closeFileDescriptorsEv;
- _ZN7android6Parcel22writeDupFileDescriptorEi;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZN7android6Parcel25writeParcelFileDescriptorEib;
- _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
- _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
- _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
- _ZN7android6Parcel4Blob4initEiPvmb;
- _ZN7android6Parcel4Blob5clearEv;
- _ZN7android6Parcel4Blob7releaseEv;
- _ZN7android6Parcel4BlobC1Ev;
- _ZN7android6Parcel4BlobC2Ev;
- _ZN7android6Parcel4BlobD1Ev;
- _ZN7android6Parcel4BlobD2Ev;
- _ZN7android6Parcel5writeEPKvm;
- _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
- _ZN7android6Parcel7setDataEPKhm;
- _ZN7android6Parcel8freeDataEv;
- _ZN7android6Parcel8growDataEm;
- _ZN7android6Parcel8setErrorEi;
- _ZN7android6Parcel9initStateEv;
- _ZN7android6Parcel9writeBlobEmbPNS0_12WritableBlobE;
- _ZN7android6Parcel9writeBoolEb;
- _ZN7android6Parcel9writeByteEa;
- _ZN7android6Parcel9writeCharEDs;
- _ZN7android6ParcelC1Ev;
- _ZN7android6ParcelC2Ev;
- _ZN7android6ParcelD1Ev;
- _ZN7android6ParcelD2Ev;
- _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinder10pingBinderEv;
- _ZN7android7BBinder11getDebugPidEv;
- _ZN7android7BBinder11isInheritRtEv;
- _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android7BBinder11localBinderEv;
- _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android7BBinder12detachObjectEPKv;
- _ZN7android7BBinder12getExtensionEv;
- _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
- _ZN7android7BBinder12setInheritRtEb;
- _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android7BBinder15isRequestingSidEv;
- _ZN7android7BBinder16setRequestingSidEb;
- _ZN7android7BBinder17getOrCreateExtrasEv;
- _ZN7android7BBinder21getMinSchedulerPolicyEv;
- _ZN7android7BBinder21setMinSchedulerPolicyEii;
- _ZN7android7BBinder23getMinSchedulerPriorityEv;
- _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android7BBinderC1Ev;
- _ZN7android7BBinderC2Ev;
- _ZN7android7BBinderD0Ev;
- _ZN7android7BBinderD1Ev;
- _ZN7android7BBinderD2Ev;
- _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
- _ZN7android7content2pm21IPackageManagerNative10descriptorE;
- _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm21IPackageManagerNative12default_implE;
- _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
- _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm21IPackageManagerNativeC2Ev;
- _ZN7android7content2pm21IPackageManagerNativeD0Ev;
- _ZN7android7content2pm21IPackageManagerNativeD1Ev;
- _ZN7android7content2pm21IPackageManagerNativeD2Ev;
- _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
- _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
- _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
- _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
- _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
- _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPl;
- _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
- _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
- _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
- _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
- _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm22IPackageChangeObserver12default_implE;
- _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
- _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
- _ZN7android7content2pm22IPackageChangeObserverC2Ev;
- _ZN7android7content2pm22IPackageChangeObserverD0Ev;
- _ZN7android7content2pm22IPackageChangeObserverD1Ev;
- _ZN7android7content2pm22IPackageChangeObserverD2Ev;
- _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
- _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
- _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android7HexDumpC1EPKvmm;
- _ZN7android7HexDumpC2EPKvmm;
- _ZN7android7IBinder11getDebugPidEPi;
- _ZN7android7IBinder11localBinderEv;
- _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
- _ZN7android7IBinder12remoteBinderEv;
- _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
- _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
- _ZN7android7IBinderC2Ev;
- _ZN7android7IBinderD0Ev;
- _ZN7android7IBinderD1Ev;
- _ZN7android7IBinderD2Ev;
- _ZN7android7IMemory10descriptorE;
- _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
- _ZN7android7IMemory12default_implE;
- _ZN7android7IMemory14getDefaultImplEv;
- _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
- _ZN7android7IMemoryC2Ev;
- _ZN7android7IMemoryD0Ev;
- _ZN7android7IMemoryD1Ev;
- _ZN7android7IMemoryD2Ev;
- _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BnMemoryC2Ev;
- _ZN7android8BnMemoryD0Ev;
- _ZN7android8BnMemoryD1Ev;
- _ZN7android8BnMemoryD2Ev;
- _ZN7android8BpBinder10onFirstRefEv;
- _ZN7android8BpBinder10pingBinderEv;
- _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
- _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
- _ZN7android8BpBinder12detachObjectEPKv;
- _ZN7android8BpBinder12remoteBinderEv;
- _ZN7android8BpBinder12sendObituaryEv;
- _ZN7android8BpBinder12sTrackingMapE;
- _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
- _ZN7android8BpBinder13ObjectManager4killEv;
- _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
- _ZN7android8BpBinder13ObjectManager6detachEPKv;
- _ZN7android8BpBinder13ObjectManagerC1Ev;
- _ZN7android8BpBinder13ObjectManagerC2Ev;
- _ZN7android8BpBinder13ObjectManagerD1Ev;
- _ZN7android8BpBinder13ObjectManagerD2Ev;
- _ZN7android8BpBinder13sTrackingLockE;
- _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
- _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
- _ZN7android8BpBinder14sLimitCallbackE;
- _ZN7android8BpBinder15onLastStrongRefEPKv;
- _ZN7android8BpBinder15sNumTrackedUidsE;
- _ZN7android8BpBinder16enableCountByUidEv;
- _ZN7android8BpBinder16setLimitCallbackEPFviE;
- _ZN7android8BpBinder17disableCountByUidEv;
- _ZN7android8BpBinder18sCountByUidEnabledE;
- _ZN7android8BpBinder19getBinderProxyCountEj;
- _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZN7android8BpBinder20setCountByUidEnabledEb;
- _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
- _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
- _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
- _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
- _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
- _ZN7android8BpBinder6createEi;
- _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
- _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC1EONS0_9RpcHandleE;
- _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
- _ZN7android8BpBinderC2EONS0_9RpcHandleE;
- _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
- _ZN7android8BpBinderD0Ev;
- _ZN7android8BpBinderD1Ev;
- _ZN7android8BpBinderD2Ev;
- _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android8BpMemoryD0Ev;
- _ZN7android8BpMemoryD1Ev;
- _ZN7android8BpMemoryD2Ev;
- _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
- _ZN7android8internal9Stability11levelStringENS1_5LevelE;
- _ZN7android8internal9Stability13getLocalLevelEv;
- _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
- _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
- _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
- _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
- _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
- _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
- _ZN7android8internal9Stability8Category11debugStringEv;
- _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
- _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
- _ZN7android8RpcState11CommandDataC1Em;
- _ZN7android8RpcState11CommandDataC2Em;
- _ZN7android8RpcState12countBindersEv;
- _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
- _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
- _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPm;
- _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
- _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
- _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
- _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
- _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
- _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
- _ZN7android8RpcState4dumpEv;
- _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvm;
- _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvm;
- _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
- _ZN7android8RpcState9terminateEv;
- _ZN7android8RpcStateC1Ev;
- _ZN7android8RpcStateC2Ev;
- _ZN7android8RpcStateD1Ev;
- _ZN7android8RpcStateD2Ev;
- _ZN7android9BpRefBase10onFirstRefEv;
- _ZN7android9BpRefBase15onLastStrongRefEPKv;
- _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
- _ZN7android9BpRefBaseD0Ev;
- _ZN7android9BpRefBaseD1Ev;
- _ZN7android9BpRefBaseD2Ev;
- _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCache10dump_heapsEv;
- _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
- _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
- _ZN7android9HeapCacheC1Ev;
- _ZN7android9HeapCacheC2Ev;
- _ZN7android9HeapCacheD0Ev;
- _ZN7android9HeapCacheD1Ev;
- _ZN7android9HeapCacheD2Ev;
- _ZN7android9hexStringEPKvm;
- _ZN7android9RpcServer12listSessionsEv;
- _ZN7android9RpcServer13getMaxThreadsEv;
- _ZN7android9RpcServer13getRootObjectEv;
- _ZN7android9RpcServer13releaseServerEv;
- _ZN7android9RpcServer13setMaxThreadsEm;
- _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
- _ZN7android9RpcServer15setupInetServerEjPj;
- _ZN7android9RpcServer16setupVsockServerEj;
- _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
- _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
- _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
- _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
- _ZN7android9RpcServer21setupUnixDomainServerEPKc;
- _ZN7android9RpcServer24numUninitializedSessionsEv;
- _ZN7android9RpcServer4joinEv;
- _ZN7android9RpcServer4makeEv;
- _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
- _ZN7android9RpcServer9acceptOneEv;
- _ZN7android9RpcServer9hasServerEv;
- _ZN7android9RpcServerC1Ev;
- _ZN7android9RpcServerC2Ev;
- _ZN7android9RpcServerD0Ev;
- _ZN7android9RpcServerD1Ev;
- _ZN7android9RpcServerD2Ev;
- _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
- _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
- _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsImEERNS_10TextOutputES2_RKT_;
- _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
- _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
- _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
- _ZNK7android10MemoryBase9getMemoryEPlPm;
- _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
- _ZNK7android10RpcAddress15viewRawEmbeddedEv;
- _ZNK7android10RpcAddress6isZeroEv;
- _ZNK7android10RpcAddress8toStringEv;
- _ZNK7android10RpcAddressltERKS0_;
- _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
- _ZNK7android12BpMemoryHeap12assertMappedEv;
- _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
- _ZNK7android12BpMemoryHeap7getBaseEv;
- _ZNK7android12BpMemoryHeap7getSizeEv;
- _ZNK7android12BpMemoryHeap8getFlagsEv;
- _ZNK7android12BpMemoryHeap9getHeapIDEv;
- _ZNK7android12BpMemoryHeap9getOffsetEv;
- _ZNK7android12MemoryDealer4dumpEPKc;
- _ZNK7android12MemoryDealer4heapEv;
- _ZNK7android12MemoryDealer9allocatorEv;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvm;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_m;
- _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_m;
- _ZNK7android14IPCThreadState13getCallingPidEv;
- _ZNK7android14IPCThreadState13getCallingSidEv;
- _ZNK7android14IPCThreadState13getCallingUidEv;
- _ZNK7android14IPCThreadState18getCallRestrictionEv;
- _ZNK7android14IPCThreadState19getStrictModePolicyEv;
- _ZNK7android14IPCThreadState22getServingStackPointerEv;
- _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
- _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
- _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
- _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
- _ZNK7android14MemoryHeapBase7getBaseEv;
- _ZNK7android14MemoryHeapBase7getSizeEv;
- _ZNK7android14MemoryHeapBase8getFlagsEv;
- _ZNK7android14MemoryHeapBase9getDeviceEv;
- _ZNK7android14MemoryHeapBase9getHeapIDEv;
- _ZNK7android14MemoryHeapBase9getOffsetEv;
- _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
- _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android18BufferedTextOutput9getBufferEv;
- _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
- _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
- _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
- _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
- _ZNK7android22SimpleBestFitAllocator4sizeEv;
- _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
- _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
- _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
- _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
- _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
- _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
- _ZNK7android2os17PersistableBundle10getIntKeysEv;
- _ZNK7android2os17PersistableBundle11getLongKeysEv;
- _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
- _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
- _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIlNS5_9allocatorIlEEEE;
- _ZNK7android2os17PersistableBundle13getStringKeysEv;
- _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
- _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
- _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
- _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
- _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
- _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
- _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
- _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
- _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
- _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
- _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
- _ZNK7android2os17PersistableBundle4sizeEv;
- _ZNK7android2os17PersistableBundle5emptyEv;
- _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
- _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPl;
- _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
- _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
- _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
- _ZNK7android6binder6Status9toString8Ev;
- _ZNK7android6Parcel10errorCheckEv;
- _ZNK7android6Parcel10ipcObjectsEv;
- _ZNK7android6Parcel10readDoubleEPd;
- _ZNK7android6Parcel10readDoubleEv;
- _ZNK7android6Parcel10readObjectEb;
- _ZNK7android6Parcel10readUint32EPj;
- _ZNK7android6Parcel10readUint32Ev;
- _ZNK7android6Parcel10readUint64EPm;
- _ZNK7android6Parcel10readUint64Ev;
- _ZNK7android6Parcel10scanForFdsEv;
- _ZNK7android6Parcel11ipcDataSizeEv;
- _ZNK7android6Parcel11readCStringEv;
- _ZNK7android6Parcel11readInplaceEm;
- _ZNK7android6Parcel11readPointerEPm;
- _ZNK7android6Parcel11readPointerEv;
- _ZNK7android6Parcel11readString8EPNS_7String8E;
- _ZNK7android6Parcel11readString8Ev;
- _ZNK7android6Parcel12dataCapacityEv;
- _ZNK7android6Parcel12dataPositionEv;
- _ZNK7android6Parcel12objectsCountEv;
- _ZNK7android6Parcel12readString16EPNS_8String16E;
- _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
- _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
- _ZNK7android6Parcel12readString16Ev;
- _ZNK7android6Parcel13markSensitiveEv;
- _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
- _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
- _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
- _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
- _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
- _ZNK7android6Parcel15ipcObjectsCountEv;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
- _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
- _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIlNS1_9allocatorIlEEEE;
- _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
- _ZNK7android6Parcel15setDataPositionEm;
- _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16enforceInterfaceEPKDsmPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
- _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
- _ZNK7android6Parcel16readNativeHandleEv;
- _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel16readStrongBinderEv;
- _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorImNS1_9allocatorImEEEE;
- _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
- _ZNK7android6Parcel16validateReadDataEm;
- _ZNK7android6Parcel17getBlobAshmemSizeEv;
- _ZNK7android6Parcel17getOpenAshmemSizeEv;
- _ZNK7android6Parcel17readExceptionCodeEv;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
- _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
- _ZNK7android6Parcel18hasFileDescriptorsEv;
- _ZNK7android6Parcel18readFileDescriptorEv;
- _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
- _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
- _ZNK7android6Parcel18readString8InplaceEPm;
- _ZNK7android6Parcel19readString16InplaceEPm;
- _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
- _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
- _ZNK7android6Parcel24readCallingWorkSourceUidEv;
- _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
- _ZNK7android6Parcel24readParcelFileDescriptorEv;
- _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
- _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
- _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
- _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
- _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
- _ZNK7android6Parcel4dataEv;
- _ZNK7android6Parcel4readEPvm;
- _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
- _ZNK7android6Parcel5printERNS_10TextOutputEj;
- _ZNK7android6Parcel7ipcDataEv;
- _ZNK7android6Parcel8allowFdsEv;
- _ZNK7android6Parcel8dataSizeEv;
- _ZNK7android6Parcel8isForRpcEv;
- _ZNK7android6Parcel8readBlobEmPNS0_12ReadableBlobE;
- _ZNK7android6Parcel8readBoolEPb;
- _ZNK7android6Parcel8readBoolEv;
- _ZNK7android6Parcel8readByteEPa;
- _ZNK7android6Parcel8readByteEv;
- _ZNK7android6Parcel8readCharEPDs;
- _ZNK7android6Parcel8readCharEv;
- _ZNK7android6Parcel9dataAvailEv;
- _ZNK7android6Parcel9readFloatEPf;
- _ZNK7android6Parcel9readFloatEv;
- _ZNK7android6Parcel9readInt32EPi;
- _ZNK7android6Parcel9readInt32Ev;
- _ZNK7android6Parcel9readInt64EPl;
- _ZNK7android6Parcel9readInt64Ev;
- _ZNK7android6VectorIiE10do_destroyEPvm;
- _ZNK7android6VectorIiE12do_constructEPvm;
- _ZNK7android6VectorIiE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIiE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIiE7do_copyEPvPKvm;
- _ZNK7android6VectorIiE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvm;
- _ZNK7android6VectorINS_8String16EE10do_destroyEPvm;
- _ZNK7android6VectorINS_8String16EE12do_constructEPvm;
- _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvm;
- _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvm;
- _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvm;
- _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvm;
- _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvm;
- _ZNK7android7BBinder10findObjectEPKv;
- _ZNK7android7BBinder13isBinderAliveEv;
- _ZNK7android7BBinder22getInterfaceDescriptorEv;
- _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
- _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
- _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
- _ZNK7android7IBinder13checkSubclassEPKv;
- _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEl;
- _ZNK7android7IMemory15unsecurePointerEv;
- _ZNK7android7IMemory22getInterfaceDescriptorEv;
- _ZNK7android7IMemory4sizeEv;
- _ZNK7android7IMemory6offsetEv;
- _ZNK7android7IMemory7pointerEv;
- _ZNK7android8BpBinder10findObjectEPKv;
- _ZNK7android8BpBinder10rpcAddressEv;
- _ZNK7android8BpBinder10rpcSessionEv;
- _ZNK7android8BpBinder11isRpcBinderEv;
- _ZNK7android8BpBinder12binderHandleEv;
- _ZNK7android8BpBinder13isBinderAliveEv;
- _ZNK7android8BpBinder13ObjectManager4findEPKv;
- _ZNK7android8BpBinder18isDescriptorCachedEv;
- _ZNK7android8BpBinder22getInterfaceDescriptorEv;
- _ZNK7android8BpMemory9getMemoryEPlPm;
- _ZTCN7android10AllocationE0_NS_10IInterfaceE;
- _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
- _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10AllocationE0_NS_7IMemoryE;
- _ZTCN7android10AllocationE0_NS_8BnMemoryE;
- _ZTCN7android10AllocationE8_NS_7BBinderE;
- _ZTCN7android10AllocationE8_NS_7IBinderE;
- _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
- _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
- _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
- _ZTCN7android10MemoryBaseE8_NS_7BBinderE;
- _ZTCN7android10MemoryBaseE8_NS_7IBinderE;
- _ZTCN7android10PoolThreadE0_NS_6ThreadE;
- _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BnMemoryHeapE8_NS_7BBinderE;
- _ZTCN7android12BnMemoryHeapE8_NS_7IBinderE;
- _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
- _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
- _ZTCN7android12BpMemoryHeapE8_NS_9BpRefBaseE;
- _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE64_NS_10IInterfaceE;
- _ZTCN7android14MemoryHeapBaseE64_NS_11BnInterfaceINS_11IMemoryHeapEEE;
- _ZTCN7android14MemoryHeapBaseE64_NS_11IMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE64_NS_12BnMemoryHeapE;
- _ZTCN7android14MemoryHeapBaseE72_NS_7BBinderE;
- _ZTCN7android14MemoryHeapBaseE72_NS_7IBinderE;
- _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BnShellCallbackE8_NS_7BBinderE;
- _ZTCN7android15BnShellCallbackE8_NS_7IBinderE;
- _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
- _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
- _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
- _ZTCN7android15BpShellCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BnResultReceiverE8_NS_7BBinderE;
- _ZTCN7android16BnResultReceiverE8_NS_7IBinderE;
- _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
- _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
- _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
- _ZTCN7android16BpResultReceiverE8_NS_9BpRefBaseE;
- _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
- _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
- _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BnClientCallbackE8_NS_7BBinderE;
- _ZTCN7android2os16BnClientCallbackE8_NS_7IBinderE;
- _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BnServiceManagerE8_NS_7BBinderE;
- _ZTCN7android2os16BnServiceManagerE8_NS_7IBinderE;
- _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
- _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
- _ZTCN7android2os16BpClientCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
- _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
- _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
- _ZTCN7android2os16BpServiceManagerE8_NS_9BpRefBaseE;
- _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BnServiceCallbackE8_NS_7BBinderE;
- _ZTCN7android2os17BnServiceCallbackE8_NS_7IBinderE;
- _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
- _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
- _ZTCN7android2os17BpServiceCallbackE8_NS_9BpRefBaseE;
- _ZTCN7android7BBinderE0_NS_7IBinderE;
- _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7BBinderE;
- _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7IBinderE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
- _ZTCN7android7content2pm22BpPackageManagerNativeE8_NS_9BpRefBaseE;
- _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7BBinderE;
- _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7IBinderE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
- _ZTCN7android7content2pm23BpPackageChangeObserverE8_NS_9BpRefBaseE;
- _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BnMemoryE8_NS_7BBinderE;
- _ZTCN7android8BnMemoryE8_NS_7IBinderE;
- _ZTCN7android8BpBinderE0_NS_7IBinderE;
- _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
- _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
- _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
- _ZTCN7android8BpMemoryE8_NS_9BpRefBaseE;
- _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
- _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE;
- _ZThn8_N7android10AllocationD0Ev;
- _ZThn8_N7android10AllocationD1Ev;
- _ZThn8_N7android10MemoryBaseD0Ev;
- _ZThn8_N7android10MemoryBaseD1Ev;
- _ZThn8_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android12BnMemoryHeapD0Ev;
- _ZThn8_N7android12BnMemoryHeapD1Ev;
- _ZThn8_N7android12BpMemoryHeapD0Ev;
- _ZThn8_N7android12BpMemoryHeapD1Ev;
- _ZThn8_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
- _ZThn8_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn8_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
- _ZThn8_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
- _ZThn8_N7android8BnMemoryD0Ev;
- _ZThn8_N7android8BnMemoryD1Ev;
- _ZThn8_N7android8BpMemoryD0Ev;
- _ZThn8_N7android8BpMemoryD1Ev;
- _ZTTN7android10AllocationE;
- _ZTTN7android10IInterfaceE;
- _ZTTN7android10MemoryBaseE;
- _ZTTN7android10PoolThreadE;
- _ZTTN7android10RpcSessionE;
- _ZTTN7android11IMemoryHeapE;
- _ZTTN7android12BnMemoryHeapE;
- _ZTTN7android12BpMemoryHeapE;
- _ZTTN7android12ProcessStateE;
- _ZTTN7android14IShellCallbackE;
- _ZTTN7android14MemoryHeapBaseE;
- _ZTTN7android15BnShellCallbackE;
- _ZTTN7android15BpShellCallbackE;
- _ZTTN7android15IResultReceiverE;
- _ZTTN7android15IServiceManagerE;
- _ZTTN7android16BnResultReceiverE;
- _ZTTN7android16BpResultReceiverE;
- _ZTTN7android18ServiceManagerShimE;
- _ZTTN7android2os15IClientCallbackE;
- _ZTTN7android2os15IServiceManagerE;
- _ZTTN7android2os16BnClientCallbackE;
- _ZTTN7android2os16BnServiceManagerE;
- _ZTTN7android2os16BpClientCallbackE;
- _ZTTN7android2os16BpServiceManagerE;
- _ZTTN7android2os16IServiceCallbackE;
- _ZTTN7android2os17BnServiceCallbackE;
- _ZTTN7android2os17BpServiceCallbackE;
- _ZTTN7android7BBinderE;
- _ZTTN7android7content2pm21IPackageManagerNativeE;
- _ZTTN7android7content2pm22BnPackageManagerNativeE;
- _ZTTN7android7content2pm22BpPackageManagerNativeE;
- _ZTTN7android7content2pm22IPackageChangeObserverE;
- _ZTTN7android7content2pm23BnPackageChangeObserverE;
- _ZTTN7android7content2pm23BpPackageChangeObserverE;
- _ZTTN7android7IBinderE;
- _ZTTN7android7IMemoryE;
- _ZTTN7android8BnMemoryE;
- _ZTTN7android8BpBinderE;
- _ZTTN7android8BpMemoryE;
- _ZTTN7android9BpRefBaseE;
- _ZTTN7android9HeapCacheE;
- _ZTTN7android9RpcServerE;
- _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
- _ZTv0_n24_N7android10AllocationD0Ev;
- _ZTv0_n24_N7android10AllocationD1Ev;
- _ZTv0_n24_N7android10IInterfaceD0Ev;
- _ZTv0_n24_N7android10IInterfaceD1Ev;
- _ZTv0_n24_N7android10MemoryBaseD0Ev;
- _ZTv0_n24_N7android10MemoryBaseD1Ev;
- _ZTv0_n24_N7android10RpcSessionD0Ev;
- _ZTv0_n24_N7android10RpcSessionD1Ev;
- _ZTv0_n24_N7android11IMemoryHeapD0Ev;
- _ZTv0_n24_N7android11IMemoryHeapD1Ev;
- _ZTv0_n24_N7android12BnMemoryHeapD0Ev;
- _ZTv0_n24_N7android12BnMemoryHeapD1Ev;
- _ZTv0_n24_N7android12BpMemoryHeapD0Ev;
- _ZTv0_n24_N7android12BpMemoryHeapD1Ev;
- _ZTv0_n24_N7android12ProcessStateD0Ev;
- _ZTv0_n24_N7android12ProcessStateD1Ev;
- _ZTv0_n24_N7android14IShellCallbackD0Ev;
- _ZTv0_n24_N7android14IShellCallbackD1Ev;
- _ZTv0_n24_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n24_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n24_N7android15IResultReceiverD0Ev;
- _ZTv0_n24_N7android15IResultReceiverD1Ev;
- _ZTv0_n24_N7android15IServiceManagerD0Ev;
- _ZTv0_n24_N7android15IServiceManagerD1Ev;
- _ZTv0_n24_N7android2os15IClientCallbackD0Ev;
- _ZTv0_n24_N7android2os15IClientCallbackD1Ev;
- _ZTv0_n24_N7android2os15IServiceManagerD0Ev;
- _ZTv0_n24_N7android2os15IServiceManagerD1Ev;
- _ZTv0_n24_N7android2os16IServiceCallbackD0Ev;
- _ZTv0_n24_N7android2os16IServiceCallbackD1Ev;
- _ZTv0_n24_N7android7BBinderD0Ev;
- _ZTv0_n24_N7android7BBinderD1Ev;
- _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD0Ev;
- _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD1Ev;
- _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD0Ev;
- _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD1Ev;
- _ZTv0_n24_N7android7IBinderD0Ev;
- _ZTv0_n24_N7android7IBinderD1Ev;
- _ZTv0_n24_N7android7IMemoryD0Ev;
- _ZTv0_n24_N7android7IMemoryD1Ev;
- _ZTv0_n24_N7android8BnMemoryD0Ev;
- _ZTv0_n24_N7android8BnMemoryD1Ev;
- _ZTv0_n24_N7android8BpBinderD0Ev;
- _ZTv0_n24_N7android8BpBinderD1Ev;
- _ZTv0_n24_N7android8BpMemoryD0Ev;
- _ZTv0_n24_N7android8BpMemoryD1Ev;
- _ZTv0_n24_N7android9BpRefBaseD0Ev;
- _ZTv0_n24_N7android9BpRefBaseD1Ev;
- _ZTv0_n24_N7android9HeapCacheD0Ev;
- _ZTv0_n24_N7android9HeapCacheD1Ev;
- _ZTv0_n24_N7android9RpcServerD0Ev;
- _ZTv0_n24_N7android9RpcServerD1Ev;
- _ZTv0_n32_N7android14MemoryHeapBaseD0Ev;
- _ZTv0_n32_N7android14MemoryHeapBaseD1Ev;
- _ZTv0_n32_N7android8BpBinder10onFirstRefEv;
- _ZTv0_n32_N7android9BpRefBase10onFirstRefEv;
- _ZTv0_n40_N7android8BpBinder15onLastStrongRefEPKv;
- _ZTv0_n40_N7android9BpRefBase15onLastStrongRefEPKv;
- _ZTv0_n48_N7android8BpBinder20onIncStrongAttemptedEjPKv;
- _ZTv0_n48_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
- _ZTv0_n56_NK7android14MemoryHeapBase9getHeapIDEv;
- _ZTv0_n64_NK7android14MemoryHeapBase7getBaseEv;
- _ZTv0_n72_NK7android14MemoryHeapBase7getSizeEv;
- _ZTv0_n80_NK7android14MemoryHeapBase8getFlagsEv;
- _ZTv0_n88_NK7android14MemoryHeapBase9getOffsetEv;
- _ZTVN7android10AllocationE;
- _ZTVN7android10IInterfaceE;
- _ZTVN7android10MemoryBaseE;
- _ZTVN7android10PoolThreadE;
- _ZTVN7android10RpcSession13RpcConnectionE;
- _ZTVN7android10RpcSessionE;
- _ZTVN7android10TextOutputE;
- _ZTVN7android11IMemoryHeapE;
- _ZTVN7android12BnMemoryHeapE;
- _ZTVN7android12BpMemoryHeapE;
- _ZTVN7android12FdTextOutputE;
- _ZTVN7android12MemoryDealerE;
- _ZTVN7android12ProcessStateE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
- _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
- _ZTVN7android13LogTextOutputE;
- _ZTVN7android14IShellCallbackE;
- _ZTVN7android14MemoryHeapBaseE;
- _ZTVN7android15BnShellCallbackE;
- _ZTVN7android15BpShellCallbackE;
- _ZTVN7android15IResultReceiverE;
- _ZTVN7android15IServiceManagerE;
- _ZTVN7android16BnResultReceiverE;
- _ZTVN7android16BpResultReceiverE;
- _ZTVN7android17InetSocketAddressE;
- _ZTVN7android17UnixSocketAddressE;
- _ZTVN7android18BufferedTextOutput11BufferStateE;
- _ZTVN7android18BufferedTextOutputE;
- _ZTVN7android18ServiceManagerShimE;
- _ZTVN7android18VsockSocketAddressE;
- _ZTVN7android2os15IClientCallbackE;
- _ZTVN7android2os15IServiceManagerE;
- _ZTVN7android2os16BnClientCallbackE;
- _ZTVN7android2os16BnServiceManagerE;
- _ZTVN7android2os16BpClientCallbackE;
- _ZTVN7android2os16BpServiceManagerE;
- _ZTVN7android2os16IServiceCallbackE;
- _ZTVN7android2os16ParcelableHolderE;
- _ZTVN7android2os16ServiceDebugInfoE;
- _ZTVN7android2os17BnServiceCallbackE;
- _ZTVN7android2os17BpServiceCallbackE;
- _ZTVN7android2os17PersistableBundleE;
- _ZTVN7android2os20ParcelFileDescriptorE;
- _ZTVN7android6VectorIiEE;
- _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
- _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
- _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
- _ZTVN7android6VectorINS_8String16EEE;
- _ZTVN7android6VectorIPNS_7BBinderEEE;
- _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
- _ZTVN7android6VectorIPNS_7RefBaseEEE;
- _ZTVN7android7BBinderE;
- _ZTVN7android7content2pm18PackageChangeEventE;
- _ZTVN7android7content2pm21IPackageManagerNativeE;
- _ZTVN7android7content2pm22BnPackageManagerNativeE;
- _ZTVN7android7content2pm22BpPackageManagerNativeE;
- _ZTVN7android7content2pm22IPackageChangeObserverE;
- _ZTVN7android7content2pm23BnPackageChangeObserverE;
- _ZTVN7android7content2pm23BpPackageChangeObserverE;
- _ZTVN7android7IBinderE;
- _ZTVN7android7IMemoryE;
- _ZTVN7android8BnMemoryE;
- _ZTVN7android8BpBinderE;
- _ZTVN7android8BpMemoryE;
- _ZTVN7android9BpRefBaseE;
- _ZTVN7android9HeapCacheE;
- _ZTVN7android9RpcServerE;
- _ZTvn8_n32_N7android14MemoryHeapBaseD0Ev;
- _ZTvn8_n32_N7android14MemoryHeapBaseD1Ev;
- local:
- *;
-};
diff --git a/libs/binder/libbinder.map b/libs/binder/libbinder.map
new file mode 100644
index 0000000..9ca14bc
--- /dev/null
+++ b/libs/binder/libbinder.map
@@ -0,0 +1,5 @@
+# b/190148312: Populate with correct list of ABI symbols
+LIBBINDER {
+ global:
+ *;
+};
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
new file mode 100644
index 0000000..68ec669
--- /dev/null
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_libbinder.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcSession.h>
+
+using android::RpcServer;
+using android::RpcSession;
+
+extern "C" {
+
+bool RunRpcServer(AIBinder* service, unsigned int port) {
+ auto server = RpcServer::make();
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ if (!server->setupVsockServer(port)) {
+ LOG(ERROR) << "Failed to set up vsock server with port " << port;
+ return false;
+ }
+ server->setRootObject(AIBinder_toPlatformBinder(service));
+ server->join();
+
+ // Shutdown any open sessions since server failed.
+ (void)server->shutdown();
+ return true;
+}
+
+AIBinder* RpcClient(unsigned int cid, unsigned int port) {
+ auto session = RpcSession::make();
+ if (!session->setupVsockClient(cid, port)) {
+ LOG(ERROR) << "Failed to set up vsock client with CID " << cid << " and port " << port;
+ return nullptr;
+ }
+ return AIBinder_fromPlatformBinder(session->getRootObject());
+}
+}
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
new file mode 100644
index 0000000..3921a4d
--- /dev/null
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -0,0 +1,7 @@
+LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
+ global:
+ RunRpcServer;
+ RpcClient;
+ local:
+ *;
+};
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 1dcb41b..785e032 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -47,7 +47,8 @@
void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */};
static void attach(const sp<IBinder>& binder) {
- binder->attachObject(kId, kValue, nullptr /*cookie*/, clean);
+ // can only attach once
+ CHECK_EQ(nullptr, binder->attachObject(kId, kValue, nullptr /*cookie*/, clean));
}
static bool has(const sp<IBinder>& binder) {
return binder != nullptr && binder->findObject(kId) == kValue;
@@ -57,7 +58,6 @@
namespace ABpBinderTag {
-static std::mutex gLock;
static const void* kId = "ABpBinder";
struct Value {
wp<ABpBinder> binder;
@@ -232,19 +232,16 @@
ABpBinder::~ABpBinder() {}
void ABpBinder::onLastStrongRef(const void* id) {
- {
- std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);
- // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for
- // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no
- // longer be able to exist at the time of this method call, there is no longer a need to
- // recover it.
+ // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for
+ // the ABpBinder to be deleted. Even though we have no more references on the ABpBinder
+ // (BpRefBase), the remote object may still exist (for instance, if we
+ // receive it from another process, before the ABpBinder is attached).
- ABpBinderTag::Value* value =
- static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId));
- if (value != nullptr) {
- value->binder = nullptr;
- }
- }
+ ABpBinderTag::Value* value =
+ static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId));
+ CHECK_NE(nullptr, value) << "ABpBinder must always be attached";
+
+ remote()->withLock([&]() { value->binder = nullptr; });
BpRefBase::onLastStrongRef(id);
}
@@ -259,21 +256,29 @@
// The following code ensures that for a given binder object (remote or local), if it is not an
// ABBinder then at most one ABpBinder object exists in a given process representing it.
- std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);
- ABpBinderTag::Value* value =
- static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
+ auto* value = static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
if (value == nullptr) {
value = new ABpBinderTag::Value;
- binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), nullptr /*cookie*/,
- ABpBinderTag::clean);
+ auto oldValue = static_cast<ABpBinderTag::Value*>(
+ binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value),
+ nullptr /*cookie*/, ABpBinderTag::clean));
+
+ // allocated by another thread
+ if (oldValue) {
+ delete value;
+ value = oldValue;
+ }
}
- sp<ABpBinder> ret = value->binder.promote();
- if (ret == nullptr) {
- ret = new ABpBinder(binder);
- value->binder = ret;
- }
+ sp<ABpBinder> ret;
+ binder->withLock([&]() {
+ ret = value->binder.promote();
+ if (ret == nullptr) {
+ ret = sp<ABpBinder>::make(binder);
+ value->binder = ret;
+ }
+ });
return ret;
}
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index 6824306..3b515ab 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -105,6 +105,7 @@
ABpBinder* asABpBinder() override { return this; }
private:
+ friend android::sp<ABpBinder>;
explicit ABpBinder(const ::android::sp<::android::IBinder>& binder);
};
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
index 83190aa..5092d87 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
@@ -910,6 +910,9 @@
if (err != STATUS_OK) return err;
if (size < 0) return STATUS_UNEXPECTED_NULL;
+ // TODO(b/188215728): delegate to libbinder_ndk
+ if (size > 1000000) return STATUS_NO_MEMORY;
+
vec->resize(static_cast<size_t>(size));
return STATUS_OK;
}
@@ -931,6 +934,9 @@
return STATUS_OK;
}
+ // TODO(b/188215728): delegate to libbinder_ndk
+ if (size > 1000000) return STATUS_NO_MEMORY;
+
*vec = std::optional<std::vector<T>>(std::vector<T>{});
(*vec)->resize(static_cast<size_t>(size));
return STATUS_OK;
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index 2277148..aa3b978 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -46,7 +46,7 @@
AParcelableHolder() = delete;
explicit AParcelableHolder(parcelable_stability_t stability)
: mParcel(AParcel_create()), mStability(stability) {}
-
+ AParcelableHolder(AParcelableHolder&& other) = default;
virtual ~AParcelableHolder() = default;
binder_status_t writeToParcel(AParcel* parcel) const {
diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
index 6372449..b24094e 100644
--- a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
@@ -33,7 +33,6 @@
#endif
-#if !defined(__ANDROID_APEX__)
/**
* Data written to the parcel will be zero'd before being deleted or realloced.
*
@@ -44,6 +43,5 @@
* \param parcel The parcel to clear associated data from.
*/
void AParcel_markSensitive(const AParcel* parcel);
-#endif
__END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 7d4b82e..685ebb5 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -117,7 +117,7 @@
ABinderProcess_setupPolling; # apex
AIBinder_getCallingSid; # apex
AIBinder_setRequestingSid; # apex
- AParcel_markSensitive; # llndk
+ AParcel_markSensitive; # systemapi llndk
AServiceManager_forEachDeclaredInstance; # apex llndk
AServiceManager_forceLazyServicesPersist; # llndk
AServiceManager_isDeclared; # apex llndk
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index ec7c7d8..b2f21c7 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -46,7 +46,8 @@
template <typename T>
using ArraySetter = void (*)(void* arrayData, size_t index, T value);
-binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray, int32_t length) {
+static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
+ int32_t length) {
// only -1 can be used to represent a null array
if (length < -1) return STATUS_BAD_VALUE;
@@ -61,12 +62,24 @@
Parcel* rawParcel = parcel->get();
- status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
+ status_t status = rawParcel->writeInt32(length);
if (status != STATUS_OK) return PruneStatusT(status);
return STATUS_OK;
}
+static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
+ if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
+ return PruneStatusT(status);
+ }
+
+ if (*length < -1) return STATUS_BAD_VALUE; // libbinder_ndk reserves these
+ if (*length <= 0) return STATUS_OK; // null
+ if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
+
+ return STATUS_OK;
+}
+
template <typename T>
binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
@@ -111,10 +124,9 @@
const Parcel* rawParcel = parcel->get();
int32_t length;
- status_t status = rawParcel->readInt32(&length);
-
- if (status != STATUS_OK) return PruneStatusT(status);
- if (length < -1) return STATUS_BAD_VALUE;
+ if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+ return status;
+ }
T* array;
if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -140,10 +152,9 @@
const Parcel* rawParcel = parcel->get();
int32_t length;
- status_t status = rawParcel->readInt32(&length);
-
- if (status != STATUS_OK) return PruneStatusT(status);
- if (length < -1) return STATUS_BAD_VALUE;
+ if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+ return status;
+ }
char16_t* array;
if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -155,7 +166,7 @@
if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
for (int32_t i = 0; i < length; i++) {
- status = rawParcel->readChar(array + i);
+ status_t status = rawParcel->readChar(array + i);
if (status != STATUS_OK) return PruneStatusT(status);
}
@@ -189,10 +200,9 @@
const Parcel* rawParcel = parcel->get();
int32_t length;
- status_t status = rawParcel->readInt32(&length);
-
- if (status != STATUS_OK) return PruneStatusT(status);
- if (length < -1) return STATUS_BAD_VALUE;
+ if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+ return status;
+ }
if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
@@ -200,7 +210,7 @@
for (int32_t i = 0; i < length; i++) {
T readTarget;
- status = (rawParcel->*read)(&readTarget);
+ status_t status = (rawParcel->*read)(&readTarget);
if (status != STATUS_OK) return PruneStatusT(status);
setter(arrayData, i, readTarget);
@@ -402,13 +412,10 @@
binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
AParcel_stringArrayAllocator allocator,
AParcel_stringArrayElementAllocator elementAllocator) {
- const Parcel* rawParcel = parcel->get();
-
int32_t length;
- status_t status = rawParcel->readInt32(&length);
-
- if (status != STATUS_OK) return PruneStatusT(status);
- if (length < -1) return STATUS_BAD_VALUE;
+ if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+ return status;
+ }
if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
@@ -449,13 +456,10 @@
binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
AParcel_parcelableArrayAllocator allocator,
AParcel_readParcelableElement elementReader) {
- const Parcel* rawParcel = parcel->get();
-
int32_t length;
- status_t status = rawParcel->readInt32(&length);
-
- if (status != STATUS_OK) return PruneStatusT(status);
- if (length < -1) return STATUS_BAD_VALUE;
+ if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+ return status;
+ }
if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index bb51bf0..488009f 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -73,7 +73,10 @@
"IBinderNdkUnitTest-cpp",
"IBinderNdkUnitTest-ndk_platform",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
require_root: true,
}
@@ -95,7 +98,7 @@
"libbinder_ndk",
"libutils",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: ["general-tests"],
require_root: true,
}
@@ -115,4 +118,12 @@
"IBinderNdkUnitTest.aidl",
"IEmpty.aidl",
],
+ backend: {
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ apps_enabled: false,
+ },
+ },
}
diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
index ecbd649..a626d39 100644
--- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
+++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
@@ -21,6 +21,7 @@
import IEmpty;
+@SensitiveData
interface IBinderNdkUnitTest {
int repeatInt(int a);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 62db3cf..ce12ccf 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -39,6 +39,7 @@
#include <condition_variable>
#include <iostream>
#include <mutex>
+#include <thread>
#include "android/binder_ibinder.h"
using namespace android;
@@ -270,6 +271,27 @@
EXPECT_EQ(2, out);
}
+TEST(NdkBinder, GetTestServiceStressTest) {
+ // libbinder has some complicated logic to make sure only one instance of
+ // ABpBinder is associated with each binder.
+
+ constexpr size_t kNumThreads = 10;
+ constexpr size_t kNumCalls = 1000;
+ std::vector<std::thread> threads;
+
+ for (size_t i = 0; i < kNumThreads; i++) {
+ threads.push_back(std::thread([&]() {
+ for (size_t j = 0; j < kNumCalls; j++) {
+ auto binder =
+ ndk::SpAIBinder(AServiceManager_checkService(IFoo::kSomeInstanceName));
+ EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
+ }
+ }));
+ }
+
+ for (auto& thread : threads) thread.join();
+}
+
void defaultInstanceCounter(const char* instance, void* context) {
if (strcmp(instance, "default") == 0) {
++*(size_t*)(context);
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 49d3401..8d27eed 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -26,6 +26,7 @@
},
apex_available: [
"//apex_available:platform",
+ "com.android.compos",
"com.android.virt",
],
}
@@ -48,6 +49,7 @@
},
apex_available: [
"//apex_available:platform",
+ "com.android.compos",
"com.android.virt",
],
lints: "none",
@@ -99,6 +101,22 @@
},
apex_available: [
"//apex_available:platform",
+ "com.android.compos",
+ "com.android.virt",
+ ],
+}
+
+// TODO(b/184872979): remove once the Rust API is created.
+rust_bindgen {
+ name: "libbinder_rpc_unstable_bindgen",
+ wrapper_src: "src/binder_rpc_unstable.hpp",
+ crate_name: "binder_rpc_unstable_bindgen",
+ source_stem: "bindings",
+ shared_libs: [
+ "libutils",
+ ],
+ apex_available: [
+ "com.android.compos",
"com.android.virt",
],
}
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 695a83e..dd0c7b8 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -25,6 +25,7 @@
use std::cmp::Ordering;
use std::ffi::{c_void, CStr, CString};
use std::fmt;
+use std::fs::File;
use std::marker::PhantomData;
use std::ops::Deref;
use std::os::raw::c_char;
@@ -49,11 +50,19 @@
/// interfaces) must implement this trait.
///
/// This is equivalent `IInterface` in C++.
-pub trait Interface: Send {
+pub trait Interface: Send + Sync {
/// Convert this binder object into a generic [`SpIBinder`] reference.
fn as_binder(&self) -> SpIBinder {
panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
}
+
+ /// Dump transaction handler for this Binder object.
+ ///
+ /// This handler is a no-op by default and should be implemented for each
+ /// Binder service struct that wishes to respond to dump transactions.
+ fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
+ Ok(())
+ }
}
/// Interface stability promise
@@ -98,6 +107,10 @@
/// `reply` may be [`None`] if the sender does not expect a reply.
fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
+ /// Handle a request to invoke the dump transaction on this
+ /// object.
+ fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
+
/// Retrieve the class of this remote object.
///
/// This method should always return the same InterfaceClass for the same
@@ -218,7 +231,7 @@
if class.is_null() {
panic!("Expected non-null class pointer from AIBinder_Class_define!");
}
- sys::AIBinder_Class_setOnDump(class, None);
+ sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
sys::AIBinder_Class_setHandleShellCommand(class, None);
class
};
@@ -492,6 +505,16 @@
/// returned by `on_create` for this class. This function takes ownership of
/// the provided pointer and destroys it.
unsafe extern "C" fn on_destroy(object: *mut c_void);
+
+ /// Called to handle the `dump` transaction.
+ ///
+ /// # Safety
+ ///
+ /// Must be called with a non-null, valid pointer to a local `AIBinder` that
+ /// contains a `T` pointer in its user data. fd should be a non-owned file
+ /// descriptor, and args must be an array of null-terminated string
+ /// poiinters with length num_args.
+ unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t;
}
/// Interface for transforming a generic SpIBinder into a specific remote
@@ -778,6 +801,10 @@
}
}
+ fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> {
+ self.0.dump(file, args)
+ }
+
fn get_class() -> $crate::InterfaceClass {
static CLASS_INIT: std::sync::Once = std::sync::Once::new();
static mut CLASS: Option<$crate::InterfaceClass> = None;
@@ -870,7 +897,7 @@
#[macro_export]
macro_rules! declare_binder_enum {
{
- $enum:ident : $backing:ty {
+ $enum:ident : [$backing:ty; $size:expr] {
$( $name:ident = $value:expr, )*
}
} => {
@@ -878,6 +905,11 @@
pub struct $enum(pub $backing);
impl $enum {
$( pub const $name: Self = Self($value); )*
+
+ #[inline(always)]
+ pub const fn enum_values() -> [Self; $size] {
+ [$(Self::$name),*]
+ }
}
impl $crate::parcel::Serialize for $enum {
diff --git a/libs/ui/Size.cpp b/libs/binder/rust/src/binder_rpc_unstable.hpp
similarity index 71%
copy from libs/ui/Size.cpp
copy to libs/binder/rust/src/binder_rpc_unstable.hpp
index d2996d1..7932d0f 100644
--- a/libs/ui/Size.cpp
+++ b/libs/binder/rust/src/binder_rpc_unstable.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 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,13 @@
* limitations under the License.
*/
-#include <ui/Size.h>
+#pragma once
-namespace android::ui {
+extern "C" {
-const Size Size::INVALID{-1, -1};
-const Size Size::EMPTY{0, 0};
+struct AIBinder;
-} // namespace android::ui
+bool RunRpcServer(AIBinder* service, unsigned int port);
+AIBinder* RpcClient(unsigned int cid, unsigned int port);
+
+}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 2694cba..cb330a6 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -115,14 +115,21 @@
pub use native::add_service;
pub use native::Binder;
pub use parcel::Parcel;
-pub use proxy::{get_interface, get_service};
+pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service};
pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
pub use state::{ProcessState, ThreadState};
+/// Unstable, in-development API that only allowlisted clients are allowed to use.
+pub mod unstable_api {
+ pub use crate::binder::AsNative;
+ pub use crate::proxy::unstable_api::new_spibinder;
+ pub use crate::sys::AIBinder;
+}
+
/// The public API usable outside AIDL-generated interface crates.
pub mod public_api {
pub use super::parcel::ParcelFileDescriptor;
- pub use super::{add_service, get_interface};
+ pub use super::{add_service, get_interface, wait_for_interface};
pub use super::{
BinderFeatures, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder,
Status, StatusCode, Strong, ThreadState, Weak, WpIBinder,
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index 3920129..a0dfeec 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -21,9 +21,13 @@
use crate::sys;
use std::convert::TryFrom;
-use std::ffi::{c_void, CString};
+use std::ffi::{c_void, CStr, CString};
+use std::fs::File;
use std::mem::ManuallyDrop;
use std::ops::Deref;
+use std::os::raw::c_char;
+use std::os::unix::io::FromRawFd;
+use std::slice;
/// Rust wrapper around Binder remotable objects.
///
@@ -47,6 +51,25 @@
/// to how `Box<T>` is `Send` if `T` is `Send`.
unsafe impl<T: Remotable> Send for Binder<T> {}
+/// # Safety
+///
+/// A `Binder<T>` is a pair of unique owning pointers to two values:
+/// * a C++ ABBinder which is thread-safe, i.e. `Send + Sync`
+/// * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
+///
+/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a
+/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains
+/// a mutable pointer to its class, but mutation of this field is controlled by
+/// a mutex and it is only allowed to be set once, therefore we can concurrently
+/// access this field safely. `ABBinder` inherits from `BBinder`, which is also
+/// thread-safe. Thus `ABBinder` is thread-safe.
+///
+/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
+/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
+/// the box-like object inherits `Sync` from the two inner values, similarly
+/// to how `Box<T>` is `Sync` if `T` is `Sync`.
+unsafe impl<T: Remotable> Sync for Binder<T> {}
+
impl<T: Remotable> Binder<T> {
/// Create a new Binder remotable object with default stability
///
@@ -289,6 +312,37 @@
// object created by Box.
args
}
+
+ /// Called to handle the `dump` transaction.
+ ///
+ /// # Safety
+ ///
+ /// Must be called with a non-null, valid pointer to a local `AIBinder` that
+ /// contains a `T` pointer in its user data. fd should be a non-owned file
+ /// descriptor, and args must be an array of null-terminated string
+ /// poiinters with length num_args.
+ unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t {
+ if fd < 0 {
+ return StatusCode::UNEXPECTED_NULL as status_t;
+ }
+ // We don't own this file, so we need to be careful not to drop it.
+ let file = ManuallyDrop::new(File::from_raw_fd(fd));
+
+ if args.is_null() {
+ return StatusCode::UNEXPECTED_NULL as status_t;
+ }
+ let args = slice::from_raw_parts(args, num_args as usize);
+ let args: Vec<_> = args.iter().map(|s| CStr::from_ptr(*s)).collect();
+
+ let object = sys::AIBinder_getUserData(binder);
+ let binder: &T = &*(object as *const T);
+ let res = binder.on_dump(&file, &args);
+
+ match res {
+ Ok(()) => 0,
+ Err(e) => e as status_t,
+ }
+ }
}
impl<T: Remotable> Drop for Binder<T> {
@@ -409,6 +463,10 @@
Ok(())
}
+ fn on_dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
+ Ok(())
+ }
+
binder_fn_get_class!(Binder::<Self>);
}
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 6c34824..a3f7620 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -184,11 +184,17 @@
}
}
+ /// Returns the total size of the parcel.
+ pub fn get_data_size(&self) -> i32 {
+ unsafe {
+ // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
+ // and this call is otherwise safe.
+ sys::AParcel_getDataSize(self.as_native())
+ }
+ }
+
/// Move the current read/write position in the parcel.
///
- /// The new position must be a position previously returned by
- /// `self.get_data_position()`.
- ///
/// # Safety
///
/// This method is safe if `pos` is less than the current size of the parcel
@@ -219,6 +225,72 @@
D::deserialize(self)
}
+ /// Attempt to read a type that implements [`Deserialize`] from this
+ /// `Parcel` onto an existing value. This operation will overwrite the old
+ /// value partially or completely, depending on how much data is available.
+ pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
+ x.deserialize_from(self)
+ }
+
+ /// Safely read a sized parcelable.
+ ///
+ /// Read the size of a parcelable, compute the end position
+ /// of that parcelable, then build a sized readable sub-parcel
+ /// and call a closure with the sub-parcel as its parameter.
+ /// The closure can keep reading data from the sub-parcel
+ /// until it runs out of input data. The closure is responsible
+ /// for calling [`ReadableSubParcel::has_more_data`] to check for
+ /// more data before every read, at least until Rust generators
+ /// are stabilized.
+ /// After the closure returns, skip to the end of the current
+ /// parcelable regardless of how much the closure has read.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// let mut parcelable = Default::default();
+ /// parcel.sized_read(|subparcel| {
+ /// if subparcel.has_more_data() {
+ /// parcelable.a = subparcel.read()?;
+ /// }
+ /// if subparcel.has_more_data() {
+ /// parcelable.b = subparcel.read()?;
+ /// }
+ /// Ok(())
+ /// });
+ /// ```
+ ///
+ pub fn sized_read<F>(&self, mut f: F) -> Result<()>
+ where
+ for<'a> F: FnMut(ReadableSubParcel<'a>) -> Result<()>
+ {
+ let start = self.get_data_position();
+ let parcelable_size: i32 = self.read()?;
+ if parcelable_size < 0 {
+ return Err(StatusCode::BAD_VALUE);
+ }
+
+ let end = start.checked_add(parcelable_size)
+ .ok_or(StatusCode::BAD_VALUE)?;
+ if end > self.get_data_size() {
+ return Err(StatusCode::NOT_ENOUGH_DATA);
+ }
+
+ let subparcel = ReadableSubParcel {
+ parcel: self,
+ end_position: end,
+ };
+ f(subparcel)?;
+
+ // Advance the data position to the actual end,
+ // in case the closure read less data than was available
+ unsafe {
+ self.set_data_position(end)?;
+ }
+
+ Ok(())
+ }
+
/// Read a vector size from the `Parcel` and resize the given output vector
/// to be correctly sized for that amount of data.
///
@@ -264,6 +336,27 @@
}
}
+/// A segment of a readable parcel, used for [`Parcel::sized_read`].
+pub struct ReadableSubParcel<'a> {
+ parcel: &'a Parcel,
+ end_position: i32,
+}
+
+impl<'a> ReadableSubParcel<'a> {
+ /// Read a type that implements [`Deserialize`] from the sub-parcel.
+ pub fn read<D: Deserialize>(&self) -> Result<D> {
+ // The caller should have checked this,
+ // but it can't hurt to double-check
+ assert!(self.has_more_data());
+ D::deserialize(self.parcel)
+ }
+
+ /// Check if the sub-parcel has more data to read
+ pub fn has_more_data(&self) -> bool {
+ self.parcel.get_data_position() < self.end_position
+ }
+}
+
// Internal APIs
impl Parcel {
pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> {
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index f57788b..956ecfe 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -39,6 +39,14 @@
pub trait Deserialize: Sized {
/// Deserialize an instance from the given [`Parcel`].
fn deserialize(parcel: &Parcel) -> Result<Self>;
+
+ /// Deserialize an instance from the given [`Parcel`] onto the
+ /// current object. This operation will overwrite the old value
+ /// partially or completely, depending on how much data is available.
+ fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+ *self = Self::deserialize(parcel)?;
+ Ok(())
+ }
}
/// Helper trait for types that can be serialized as arrays.
@@ -184,6 +192,14 @@
parcel.read().map(Some)
}
}
+
+ /// Deserialize an Option of this type from the given [`Parcel`] onto the
+ /// current object. This operation will overwrite the current value
+ /// partially or completely, depending on how much data is available.
+ fn deserialize_option_from(this: &mut Option<Self>, parcel: &Parcel) -> Result<()> {
+ *this = Self::deserialize_option(parcel)?;
+ Ok(())
+ }
}
/// Callback to allocate a vector for parcel array read functions.
@@ -677,6 +693,75 @@
fn deserialize(parcel: &Parcel) -> Result<Self> {
DeserializeOption::deserialize_option(parcel)
}
+
+ fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+ DeserializeOption::deserialize_option_from(self, parcel)
+ }
+}
+
+/// Implement `Deserialize` trait and friends for a parcelable
+///
+/// This is an internal macro used by the AIDL compiler to implement
+/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
+/// structured parcelables. The target type must implement a
+/// `deserialize_parcelable` method with the following signature:
+/// ```no_run
+/// fn deserialize_parcelable(
+/// &mut self,
+/// parcel: &binder::parcel::Parcelable,
+/// ) -> binder::Result<()> {
+/// // ...
+/// }
+/// ```
+#[macro_export]
+macro_rules! impl_deserialize_for_parcelable {
+ ($parcelable:ident) => {
+ impl $crate::parcel::Deserialize for $parcelable {
+ fn deserialize(
+ parcel: &$crate::parcel::Parcel,
+ ) -> $crate::Result<Self> {
+ $crate::parcel::DeserializeOption::deserialize_option(parcel)
+ .transpose()
+ .unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
+ }
+ fn deserialize_from(
+ &mut self,
+ parcel: &$crate::parcel::Parcel,
+ ) -> $crate::Result<()> {
+ let status: i32 = parcel.read()?;
+ if status == 0 {
+ Err($crate::StatusCode::UNEXPECTED_NULL)
+ } else {
+ self.deserialize_parcelable(parcel)
+ }
+ }
+ }
+
+ impl $crate::parcel::DeserializeArray for $parcelable {}
+
+ impl $crate::parcel::DeserializeOption for $parcelable {
+ fn deserialize_option(
+ parcel: &$crate::parcel::Parcel,
+ ) -> $crate::Result<Option<Self>> {
+ let mut result = None;
+ Self::deserialize_option_from(&mut result, parcel)?;
+ Ok(result)
+ }
+ fn deserialize_option_from(
+ this: &mut Option<Self>,
+ parcel: &$crate::parcel::Parcel,
+ ) -> $crate::Result<()> {
+ let status: i32 = parcel.read()?;
+ if status == 0 {
+ *this = None;
+ Ok(())
+ } else {
+ this.get_or_insert_with(Self::default)
+ .deserialize_parcelable(parcel)
+ }
+ }
+ }
+ }
}
#[test]
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 52036f5..cdd7c08 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -48,9 +48,14 @@
/// # Safety
///
-/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe
+/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
unsafe impl Send for SpIBinder {}
+/// # Safety
+///
+/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
+unsafe impl Sync for SpIBinder {}
+
impl SpIBinder {
/// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
///
@@ -125,6 +130,21 @@
}
}
+pub mod unstable_api {
+ use super::{sys, SpIBinder};
+
+ /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
+ /// needed to bridge RPC binder, which doesn't have Rust API yet.
+ /// TODO(b/184872979): remove once the Rust API is created.
+ ///
+ /// # Safety
+ ///
+ /// See `SpIBinder::from_raw`.
+ pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
+ SpIBinder::from_raw(ptr)
+ }
+}
+
/// An object that can be associate with an [`InterfaceClass`].
pub trait AssociateClass {
/// Check if this object is a valid object for the given interface class
@@ -433,9 +453,14 @@
/// # Safety
///
-/// A `WpIBinder` is a handle to a C++ IBinder, which is thread-safe.
+/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
unsafe impl Send for WpIBinder {}
+/// # Safety
+///
+/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
+unsafe impl Sync for WpIBinder {}
+
impl WpIBinder {
/// Create a new weak reference from an object that can be converted into a
/// raw `AIBinder` pointer.
@@ -653,6 +678,18 @@
}
}
+/// Retrieve an existing service, or start it if it is configured as a dynamic
+/// service and isn't yet started.
+pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
+ let name = CString::new(name).ok()?;
+ unsafe {
+ // Safety: `AServiceManager_waitforService` returns either a null
+ // pointer or a valid pointer to an owned `AIBinder`. Either of these
+ // values is safe to pass to `SpIBinder::from_raw`.
+ SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
+ }
+}
+
/// Retrieve an existing service for a particular interface, blocking for a few
/// seconds if it doesn't yet exist.
pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
@@ -663,6 +700,16 @@
}
}
+/// Retrieve an existing service for a particular interface, or start it if it
+/// is configured as a dynamic service and isn't yet started.
+pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
+ let service = wait_for_service(name);
+ match service {
+ Some(service) => FromIBinder::try_from(service),
+ None => Err(StatusCode::NAME_NOT_FOUND),
+ }
+}
+
/// # Safety
///
/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 0332007..da8907d 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -23,6 +23,9 @@
FIRST_CALL_TRANSACTION,
};
use std::convert::{TryFrom, TryInto};
+use std::ffi::CStr;
+use std::fs::File;
+use std::sync::Mutex;
/// Name of service runner.
///
@@ -50,13 +53,11 @@
let extension_name = args.next();
{
- let mut service = Binder::new(BnTest(Box::new(TestService {
- s: service_name.clone(),
- })));
+ let mut service = Binder::new(BnTest(Box::new(TestService::new(&service_name))));
service.set_requesting_sid(true);
if let Some(extension_name) = extension_name {
let extension =
- BnTest::new_binder(TestService { s: extension_name }, BinderFeatures::default());
+ BnTest::new_binder(TestService::new(&extension_name), BinderFeatures::default());
service
.set_extension(&mut extension.as_binder())
.expect("Could not add extension");
@@ -80,14 +81,24 @@
));
}
-#[derive(Clone)]
struct TestService {
s: String,
+ dump_args: Mutex<Vec<String>>,
+}
+
+impl TestService {
+ fn new(s: &str) -> Self {
+ Self {
+ s: s.to_string(),
+ dump_args: Mutex::new(Vec::new()),
+ }
+ }
}
#[repr(u32)]
enum TestTransactionCode {
Test = FIRST_CALL_TRANSACTION,
+ GetDumpArgs,
GetSelinuxContext,
}
@@ -97,6 +108,7 @@
fn try_from(c: u32) -> Result<Self, Self::Error> {
match c {
_ if c == TestTransactionCode::Test as u32 => Ok(TestTransactionCode::Test),
+ _ if c == TestTransactionCode::GetDumpArgs as u32 => Ok(TestTransactionCode::GetDumpArgs),
_ if c == TestTransactionCode::GetSelinuxContext as u32 => {
Ok(TestTransactionCode::GetSelinuxContext)
}
@@ -105,13 +117,24 @@
}
}
-impl Interface for TestService {}
+impl Interface for TestService {
+ fn dump(&self, _file: &File, args: &[&CStr]) -> binder::Result<()> {
+ let mut dump_args = self.dump_args.lock().unwrap();
+ dump_args.extend(args.iter().map(|s| s.to_str().unwrap().to_owned()));
+ Ok(())
+ }
+}
impl ITest for TestService {
fn test(&self) -> binder::Result<String> {
Ok(self.s.clone())
}
+ fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+ let args = self.dump_args.lock().unwrap().clone();
+ Ok(args)
+ }
+
fn get_selinux_context(&self) -> binder::Result<String> {
let sid =
ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned()));
@@ -124,6 +147,9 @@
/// Returns a test string
fn test(&self) -> binder::Result<String>;
+ /// Return the arguments sent via dump
+ fn get_dump_args(&self) -> binder::Result<Vec<String>>;
+
/// Returns the caller's SELinux context
fn get_selinux_context(&self) -> binder::Result<String>;
}
@@ -145,6 +171,7 @@
) -> binder::Result<()> {
match code.try_into()? {
TestTransactionCode::Test => reply.write(&service.test()?),
+ TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
}
}
@@ -157,6 +184,13 @@
reply.read()
}
+ fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+ let reply =
+ self.binder
+ .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?;
+ reply.read()
+ }
+
fn get_selinux_context(&self) -> binder::Result<String> {
let reply = self.binder.transact(
TestTransactionCode::GetSelinuxContext as TransactionCode,
@@ -172,6 +206,10 @@
self.0.test()
}
+ fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+ self.0.get_dump_args()
+ }
+
fn get_selinux_context(&self) -> binder::Result<String> {
self.0.get_selinux_context()
}
@@ -274,6 +312,20 @@
}
#[test]
+ fn check_wait_for_service() {
+ let mut sm =
+ binder::wait_for_service("manager").expect("Did not get manager binder service");
+ assert!(sm.is_binder_alive());
+ assert!(sm.ping_binder().is_ok());
+
+ // The service manager service isn't an ITest, so this must fail.
+ assert_eq!(
+ binder::wait_for_interface::<dyn ITest>("manager").err(),
+ Some(StatusCode::BAD_TYPE)
+ );
+ }
+
+ #[test]
fn trivial_client() {
let service_name = "trivial_client_test";
let _process = ScopedServiceProcess::new(service_name);
@@ -283,6 +335,15 @@
}
#[test]
+ fn wait_for_trivial_client() {
+ let service_name = "wait_for_trivial_client_test";
+ let _process = ScopedServiceProcess::new(service_name);
+ let test_client: Strong<dyn ITest> =
+ binder::wait_for_interface(service_name).expect("Did not get manager binder service");
+ assert_eq!(test_client.test().unwrap(), "wait_for_trivial_client_test");
+ }
+
+ #[test]
fn get_selinux_context() {
let service_name = "get_selinux_context";
let _process = ScopedServiceProcess::new(service_name);
@@ -409,18 +470,22 @@
{
let _process = ScopedServiceProcess::new(service_name);
- let mut remote = binder::get_service(service_name);
+ let test_client: Strong<dyn ITest> =
+ binder::get_interface(service_name)
+ .expect("Did not get test binder service");
+ let mut remote = test_client.as_binder();
assert!(remote.is_binder_alive());
remote.ping_binder().expect("Could not ping remote service");
- // We're not testing the output of dump here, as that's really a
- // property of the C++ implementation. There is the risk that the
- // method just does nothing, but we don't want to depend on any
- // particular output from the underlying library.
+ let dump_args = ["dump", "args", "for", "testing"];
+
let null_out = File::open("/dev/null").expect("Could not open /dev/null");
remote
- .dump(&null_out, &[])
+ .dump(&null_out, &dump_args)
.expect("Could not dump remote service");
+
+ let remote_args = test_client.get_dump_args().expect("Could not fetched dumped args");
+ assert_eq!(dump_args, remote_args[..], "Remote args don't match call to dump");
}
// get/set_extensions is tested in test_extensions()
@@ -481,9 +546,7 @@
/// rust_ndk_interop.rs
#[test]
fn associate_existing_class() {
- let service = Binder::new(BnTest(Box::new(TestService {
- s: "testing_service".to_string(),
- })));
+ let service = Binder::new(BnTest(Box::new(TestService::new("testing_service"))));
// This should succeed although we will have to treat the service as
// remote.
@@ -497,9 +560,7 @@
fn reassociate_rust_binder() {
let service_name = "testing_service";
let service_ibinder = BnTest::new_binder(
- TestService {
- s: service_name.to_string(),
- },
+ TestService::new(service_name),
BinderFeatures::default(),
)
.as_binder();
@@ -515,9 +576,7 @@
fn weak_binder_upgrade() {
let service_name = "testing_service";
let service = BnTest::new_binder(
- TestService {
- s: service_name.to_string(),
- },
+ TestService::new(service_name),
BinderFeatures::default(),
);
@@ -533,9 +592,7 @@
let service_name = "testing_service";
let weak = {
let service = BnTest::new_binder(
- TestService {
- s: service_name.to_string(),
- },
+ TestService::new(service_name),
BinderFeatures::default(),
);
@@ -549,9 +606,7 @@
fn weak_binder_clone() {
let service_name = "testing_service";
let service = BnTest::new_binder(
- TestService {
- s: service_name.to_string(),
- },
+ TestService::new(service_name),
BinderFeatures::default(),
);
@@ -570,15 +625,11 @@
#[allow(clippy::eq_op)]
fn binder_ord() {
let service1 = BnTest::new_binder(
- TestService {
- s: "testing_service1".to_string(),
- },
+ TestService::new("testing_service1"),
BinderFeatures::default(),
);
let service2 = BnTest::new_binder(
- TestService {
- s: "testing_service2".to_string(),
- },
+ TestService::new("testing_service2"),
BinderFeatures::default(),
);
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
new file mode 100644
index 0000000..62df9b7
--- /dev/null
+++ b/libs/binder/servicedispatcher.cpp
@@ -0,0 +1,261 @@
+/*
+ * 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 <sysexits.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android/os/BnServiceManager.h>
+#include <android/os/IServiceManager.h>
+#include <binder/IServiceManager.h>
+#include <binder/RpcServer.h>
+
+using android::BBinder;
+using android::defaultServiceManager;
+using android::OK;
+using android::RpcServer;
+using android::sp;
+using android::statusToString;
+using android::String16;
+using android::base::Basename;
+using android::base::GetBoolProperty;
+using android::base::InitLogging;
+using android::base::LogdLogger;
+using android::base::LogId;
+using android::base::LogSeverity;
+using android::base::StdioLogger;
+using android::base::StringPrintf;
+using std::string_view_literals::operator""sv;
+
+namespace {
+
+using ServiceRetriever = decltype(&android::IServiceManager::checkService);
+
+int Usage(const char* program) {
+ auto basename = Basename(program);
+ auto format = R"(dispatch calls to RPC service.
+Usage:
+ %s [-g] <service_name>
+ <service_name>: the service to connect to.
+ %s [-g] manager
+ Runs an RPC-friendly service that redirects calls to servicemanager.
+
+ -g: use getService() instead of checkService().
+
+ If successful, writes port number and a new line character to stdout, and
+ blocks until killed.
+ Otherwise, writes error message to stderr and exits with non-zero code.
+)";
+ LOG(ERROR) << StringPrintf(format, basename.c_str(), basename.c_str());
+ return EX_USAGE;
+}
+
+int Dispatch(const char* name, const ServiceRetriever& serviceRetriever) {
+ auto sm = defaultServiceManager();
+ if (nullptr == sm) {
+ LOG(ERROR) << "No servicemanager";
+ return EX_SOFTWARE;
+ }
+ auto binder = std::invoke(serviceRetriever, defaultServiceManager(), String16(name));
+ if (nullptr == binder) {
+ LOG(ERROR) << "No service \"" << name << "\"";
+ return EX_SOFTWARE;
+ }
+ auto rpcServer = RpcServer::make();
+ if (nullptr == rpcServer) {
+ LOG(ERROR) << "Cannot create RpcServer";
+ return EX_SOFTWARE;
+ }
+ rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ unsigned int port;
+ if (!rpcServer->setupInetServer(0, &port)) {
+ LOG(ERROR) << "setupInetServer failed";
+ return EX_SOFTWARE;
+ }
+ auto socket = rpcServer->releaseServer();
+ auto keepAliveBinder = sp<BBinder>::make();
+ auto status = binder->setRpcClientDebug(std::move(socket), keepAliveBinder);
+ if (status != OK) {
+ LOG(ERROR) << "setRpcClientDebug failed with " << statusToString(status);
+ return EX_SOFTWARE;
+ }
+ LOG(INFO) << "Finish setting up RPC on service " << name << " on port " << port;
+
+ std::cout << port << std::endl;
+
+ TEMP_FAILURE_RETRY(pause());
+
+ PLOG(FATAL) << "TEMP_FAILURE_RETRY(pause()) exits; this should not happen!";
+ __builtin_unreachable();
+}
+
+// Wrapper that wraps a BpServiceManager as a BnServiceManager.
+class ServiceManagerProxyToNative : public android::os::BnServiceManager {
+public:
+ ServiceManagerProxyToNative(const sp<android::os::IServiceManager>& impl) : mImpl(impl) {}
+ android::binder::Status getService(const std::string&,
+ android::sp<android::IBinder>*) override {
+ // We can't send BpBinder for regular binder over RPC.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status checkService(const std::string&,
+ android::sp<android::IBinder>*) override {
+ // We can't send BpBinder for regular binder over RPC.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status addService(const std::string&, const android::sp<android::IBinder>&,
+ bool, int32_t) override {
+ // We can't send BpBinder for RPC over regular binder.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status listServices(int32_t dumpPriority,
+ std::vector<std::string>* _aidl_return) override {
+ return mImpl->listServices(dumpPriority, _aidl_return);
+ }
+ android::binder::Status registerForNotifications(
+ const std::string&, const android::sp<android::os::IServiceCallback>&) override {
+ // We can't send BpBinder for RPC over regular binder.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status unregisterForNotifications(
+ const std::string&, const android::sp<android::os::IServiceCallback>&) override {
+ // We can't send BpBinder for RPC over regular binder.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status isDeclared(const std::string& name, bool* _aidl_return) override {
+ return mImpl->isDeclared(name, _aidl_return);
+ }
+ android::binder::Status getDeclaredInstances(const std::string& iface,
+ std::vector<std::string>* _aidl_return) override {
+ return mImpl->getDeclaredInstances(iface, _aidl_return);
+ }
+ android::binder::Status updatableViaApex(const std::string& name,
+ std::optional<std::string>* _aidl_return) override {
+ return mImpl->updatableViaApex(name, _aidl_return);
+ }
+ android::binder::Status registerClientCallback(
+ const std::string&, const android::sp<android::IBinder>&,
+ const android::sp<android::os::IClientCallback>&) override {
+ // We can't send BpBinder for RPC over regular binder.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status tryUnregisterService(const std::string&,
+ const android::sp<android::IBinder>&) override {
+ // We can't send BpBinder for RPC over regular binder.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status getServiceDebugInfo(
+ std::vector<android::os::ServiceDebugInfo>* _aidl_return) override {
+ return mImpl->getServiceDebugInfo(_aidl_return);
+ }
+
+private:
+ sp<android::os::IServiceManager> mImpl;
+};
+
+// Workaround for b/191059588.
+// TODO(b/191059588): Once we can run RpcServer on single-threaded services,
+// `servicedispatcher manager` should call Dispatch("manager") directly.
+int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
+ auto sm = defaultServiceManager();
+ if (nullptr == sm) {
+ LOG(ERROR) << "No servicemanager";
+ return EX_SOFTWARE;
+ }
+ auto service = std::invoke(serviceRetriever, defaultServiceManager(), String16("manager"));
+ if (nullptr == service) {
+ LOG(ERROR) << "No service called `manager`";
+ return EX_SOFTWARE;
+ }
+ auto interface = android::os::IServiceManager::asInterface(service);
+ if (nullptr == interface) {
+ LOG(ERROR) << "Cannot cast service called `manager` to IServiceManager";
+ return EX_SOFTWARE;
+ }
+
+ // Work around restriction that doesn't allow us to send proxy over RPC.
+ interface = sp<ServiceManagerProxyToNative>::make(interface);
+ service = ServiceManagerProxyToNative::asBinder(interface);
+
+ auto rpcServer = RpcServer::make();
+ rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ rpcServer->setRootObject(service);
+ unsigned int port;
+ if (!rpcServer->setupInetServer(0, &port)) {
+ LOG(ERROR) << "Unable to set up inet server";
+ return EX_SOFTWARE;
+ }
+ LOG(INFO) << "Finish wrapping servicemanager with RPC on port " << port;
+ std::cout << port << std::endl;
+ rpcServer->join();
+
+ LOG(FATAL) << "Wrapped servicemanager exits; this should not happen!";
+ __builtin_unreachable();
+}
+
+// Log to logd. For warning and more severe messages, also log to stderr.
+class ServiceDispatcherLogger {
+public:
+ void operator()(LogId id, LogSeverity severity, const char* tag, const char* file,
+ unsigned int line, const char* message) {
+ mLogdLogger(id, severity, tag, file, line, message);
+ if (severity >= LogSeverity::WARNING) {
+ std::cout << std::flush;
+ std::cerr << Basename(getprogname()) << ": " << message << std::endl;
+ }
+ }
+
+private:
+ LogdLogger mLogdLogger{};
+};
+
+} // namespace
+
+int main(int argc, char* argv[]) {
+ InitLogging(argv, ServiceDispatcherLogger());
+
+ if (!GetBoolProperty("ro.debuggable", false)) {
+ LOG(ERROR) << "servicedispatcher is only allowed on debuggable builds.";
+ return EX_NOPERM;
+ }
+ LOG(WARNING) << "WARNING: servicedispatcher is debug only. Use with caution.";
+
+ int opt;
+ ServiceRetriever serviceRetriever = &android::IServiceManager::checkService;
+ while (-1 != (opt = getopt(argc, argv, "g"))) {
+ switch (opt) {
+ case 'g': {
+ serviceRetriever = &android::IServiceManager::getService;
+ } break;
+ default: {
+ return Usage(argv[0]);
+ }
+ }
+ }
+
+ if (optind + 1 != argc) return Usage(argv[0]);
+ auto name = argv[optind];
+
+ if (name == "manager"sv) {
+ return wrapServiceManager(serviceRetriever);
+ }
+ return Dispatch(name, serviceRetriever);
+}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index fb84f04..24afcf6 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -60,7 +60,9 @@
defaults: ["binder_test_defaults"],
srcs: ["binderLibTest.cpp"],
shared_libs: [
+ "libbase",
"libbinder",
+ "liblog",
"libutils",
],
static_libs: [
@@ -75,14 +77,14 @@
// unit test only, which can run on host and doesn't use /dev/binder
cc_test {
- name: "binderParcelTest",
+ name: "binderUnitTest",
host_supported: true,
target: {
darwin: {
enabled: false,
},
},
- srcs: ["binderParcelTest.cpp"],
+ srcs: ["binderParcelUnitTest.cpp", "binderBinderUnitTest.cpp"],
shared_libs: [
"libbinder",
"libutils",
@@ -101,7 +103,9 @@
srcs: ["binderLibTest.cpp"],
shared_libs: [
+ "libbase",
"libbinder",
+ "liblog",
"libutils",
],
static_libs: [
@@ -116,6 +120,7 @@
host_supported: true,
unstable: true,
srcs: [
+ "IBinderRpcCallback.aidl",
"IBinderRpcSession.aidl",
"IBinderRpcTest.aidl",
],
@@ -133,6 +138,9 @@
darwin: {
enabled: false,
},
+ android: {
+ test_suites: ["vts"],
+ },
},
defaults: [
"binder_test_defaults",
@@ -156,10 +164,6 @@
],
test_suites: ["general-tests"],
require_root: true,
- // Prevent the unit test target from running on sc-dev as it's not ready.
- test_options: {
- unit_test: false,
- },
}
cc_benchmark {
@@ -325,3 +329,68 @@
"libutils",
],
}
+
+cc_test_host {
+ name: "binderUtilsHostTest",
+ defaults: ["binder_test_defaults"],
+ srcs: ["binderUtilsHostTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ test_suites: ["general-tests"],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
+
+cc_test_host {
+ name: "binderHostDeviceTest",
+ defaults: ["binder_test_defaults"],
+ srcs: ["binderHostDeviceTest.cpp"],
+ test_config: "binderHostDeviceTest.xml",
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ target_required: [
+ "binderHostDeviceTestService",
+ ],
+ test_suites: ["general-tests"],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ test_options: {
+ unit_test: false,
+ },
+}
+
+cc_test {
+ name: "binderHostDeviceTestService",
+ // The binary is named differently from the module so that PushFilePreparer pushes the binary
+ // directly, not the test module directory.
+ stem: "binderHostDeviceTest-service",
+ defaults: ["binder_test_defaults"],
+ gtest: false,
+ auto_gen_config: false,
+ srcs: ["binderHostDeviceTestService.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/libs/ui/Size.cpp b/libs/binder/tests/IBinderRpcCallback.aidl
similarity index 74%
rename from libs/ui/Size.cpp
rename to libs/binder/tests/IBinderRpcCallback.aidl
index d2996d1..0336961 100644
--- a/libs/ui/Size.cpp
+++ b/libs/binder/tests/IBinderRpcCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 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.
*/
-#include <ui/Size.h>
-
-namespace android::ui {
-
-const Size Size::INVALID{-1, -1};
-const Size Size::EMPTY{0, 0};
-
-} // namespace android::ui
+interface IBinderRpcCallback {
+ void sendCallback(@utf8InCpp String str);
+ oneway void sendOnewayCallback(@utf8InCpp String str);
+}
diff --git a/libs/binder/tests/IBinderRpcTest.aidl b/libs/binder/tests/IBinderRpcTest.aidl
index ef4198d..9e10788 100644
--- a/libs/binder/tests/IBinderRpcTest.aidl
+++ b/libs/binder/tests/IBinderRpcTest.aidl
@@ -54,5 +54,11 @@
void sleepMs(int ms);
oneway void sleepMsAsync(int ms);
+ void doCallback(IBinderRpcCallback callback, boolean isOneway, boolean delayed, @utf8InCpp String value);
+ oneway void doCallbackAsync(IBinderRpcCallback callback, boolean isOneway, boolean delayed, @utf8InCpp String value);
+
void die(boolean cleanup);
+ void scheduleShutdown();
+
+ void useKernelBinderCallingId();
}
diff --git a/libs/binder/tests/binderBinderUnitTest.cpp b/libs/binder/tests/binderBinderUnitTest.cpp
new file mode 100644
index 0000000..1be0c59
--- /dev/null
+++ b/libs/binder/tests/binderBinderUnitTest.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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/Binder.h>
+#include <binder/IBinder.h>
+#include <gtest/gtest.h>
+
+using android::BBinder;
+using android::OK;
+using android::sp;
+
+const void* kObjectId1 = reinterpret_cast<const void*>(1);
+const void* kObjectId2 = reinterpret_cast<const void*>(2);
+void* kObject1 = reinterpret_cast<void*>(101);
+void* kObject2 = reinterpret_cast<void*>(102);
+void* kObject3 = reinterpret_cast<void*>(103);
+
+TEST(Binder, AttachObject) {
+ auto binder = sp<BBinder>::make();
+ EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr));
+ EXPECT_EQ(nullptr, binder->attachObject(kObjectId2, kObject2, nullptr, nullptr));
+ EXPECT_EQ(kObject1, binder->attachObject(kObjectId1, kObject3, nullptr, nullptr));
+}
+
+TEST(Binder, DetachObject) {
+ auto binder = sp<BBinder>::make();
+ EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr));
+ EXPECT_EQ(kObject1, binder->detachObject(kObjectId1));
+ EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject2, nullptr, nullptr));
+}
diff --git a/libs/binder/tests/binderHostDeviceTest.cpp b/libs/binder/tests/binderHostDeviceTest.cpp
new file mode 100644
index 0000000..5dd9212
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTest.cpp
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+// Integration test for servicedispatcher + adb forward. Requires ADB.
+
+#include <stdlib.h>
+
+#include <vector>
+
+#include <android-base/parsebool.h>
+#include <android-base/result-gmock.h>
+#include <android-base/strings.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
+
+#include "../UtilsHost.h"
+
+using ::android::setDefaultServiceManager;
+using ::android::base::EndsWith;
+using ::android::base::Join;
+using ::android::base::ParseBool;
+using ::android::base::ParseBoolResult;
+using ::android::base::Split;
+using ::android::base::StartsWith;
+using ::android::base::StringReplace;
+using ::android::base::Trim;
+using ::android::base::testing::Ok;
+using ::std::chrono_literals::operator""ms;
+using ::std::string_literals::operator""s;
+using ::testing::AllOf;
+using ::testing::Contains;
+using ::testing::ContainsRegex;
+using ::testing::ExplainMatchResult;
+using ::testing::InitGoogleMock;
+
+namespace android {
+
+namespace {
+
+constexpr const char* kServiceBinary = "/data/local/tmp/binderHostDeviceTest-service";
+constexpr const char* kServiceName = "binderHostDeviceTestService";
+constexpr const char* kDescriptor = "android.binderHostDeviceTestService";
+
+// e.g. EXPECT_THAT(expr, StatusEq(OK)) << "additional message";
+MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected)) {
+ *result_listener << statusToString(arg);
+ return expected == arg;
+}
+
+void initHostRpcServiceManagerOnce() {
+ static std::once_flag gSmOnce;
+ std::call_once(gSmOnce, [] { setDefaultServiceManager(createRpcDelegateServiceManager()); });
+}
+
+// Test for host service manager.
+class HostDeviceTest : public ::testing::Test {
+public:
+ void SetUp() override {
+ auto debuggableResult = execute(Split("adb shell getprop ro.debuggable", " "), nullptr);
+ ASSERT_THAT(debuggableResult, Ok());
+ ASSERT_EQ(0, debuggableResult->exitCode) << *debuggableResult;
+ auto debuggableBool = ParseBool(Trim(debuggableResult->stdout));
+ ASSERT_NE(ParseBoolResult::kError, debuggableBool) << Trim(debuggableResult->stdout);
+ if (debuggableBool == ParseBoolResult::kFalse) {
+ GTEST_SKIP() << "ro.debuggable=" << Trim(debuggableResult->stdout);
+ }
+
+ auto lsResult = execute(Split("adb shell which servicedispatcher", " "), nullptr);
+ ASSERT_THAT(lsResult, Ok());
+ if (lsResult->exitCode != 0) {
+ GTEST_SKIP() << "b/182914638: until feature is fully enabled, skip test on devices "
+ "without servicedispatcher";
+ }
+
+ initHostRpcServiceManagerOnce();
+ ASSERT_NE(nullptr, defaultServiceManager()) << "No defaultServiceManager() over RPC";
+
+ auto service = execute({"adb", "shell", kServiceBinary, kServiceName, kDescriptor},
+ &CommandResult::stdoutEndsWithNewLine);
+ ASSERT_THAT(service, Ok());
+ ASSERT_EQ(std::nullopt, service->exitCode) << *service;
+ mService = std::move(*service);
+ }
+ void TearDown() override { mService.reset(); }
+
+ [[nodiscard]] static sp<IBinder> get(unsigned int hostPort) {
+ auto rpcSession = RpcSession::make();
+ if (!rpcSession->setupInetClient("127.0.0.1", hostPort)) {
+ ADD_FAILURE() << "Failed to setupInetClient on " << hostPort;
+ return nullptr;
+ }
+ return rpcSession->getRootObject();
+ }
+
+private:
+ std::optional<CommandResult> mService;
+};
+
+TEST_F(HostDeviceTest, List) {
+ auto sm = defaultServiceManager();
+
+ auto services = sm->listServices();
+ ASSERT_THAT(services, Contains(String16(kServiceName)));
+}
+
+TEST_F(HostDeviceTest, CheckService) {
+ auto sm = defaultServiceManager();
+
+ auto rpcBinder = sm->checkService(String16(kServiceName));
+ ASSERT_NE(nullptr, rpcBinder);
+
+ EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+ EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, GetService) {
+ auto sm = defaultServiceManager();
+
+ auto rpcBinder = sm->getService(String16(kServiceName));
+ ASSERT_NE(nullptr, rpcBinder);
+
+ EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+ EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, WaitForService) {
+ auto sm = defaultServiceManager();
+
+ auto rpcBinder = sm->waitForService(String16(kServiceName));
+ ASSERT_NE(nullptr, rpcBinder);
+
+ EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+ EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, TenClients) {
+ auto sm = defaultServiceManager();
+
+ auto threadFn = [&] {
+ auto rpcBinder = sm->checkService(String16(kServiceName));
+ ASSERT_NE(nullptr, rpcBinder);
+
+ EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+ EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+ };
+
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < 10; ++i) threads.emplace_back(threadFn);
+ for (auto& thread : threads) thread.join();
+}
+
+} // namespace
+
+} // namespace android
diff --git a/libs/binder/tests/binderHostDeviceTest.xml b/libs/binder/tests/binderHostDeviceTest.xml
new file mode 100644
index 0000000..250ed3a
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs binderHostDeviceTest.">
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push-file" key="binderHostDeviceTest-service"
+ value="/data/local/tmp/binderHostDeviceTest-service"/>
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.binary.ExecutableHostTest">
+ <option name="binary" value="binderHostDeviceTest"/>
+ </test>
+</configuration>
diff --git a/libs/binder/tests/binderHostDeviceTestService.cpp b/libs/binder/tests/binderHostDeviceTestService.cpp
new file mode 100644
index 0000000..6ddd2e7
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTestService.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 <sysexits.h>
+
+#include <android-base/logging.h>
+#include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+namespace {
+class Service : public android::BBinder {
+public:
+ Service(std::string_view descriptor) : mDescriptor(descriptor.data(), descriptor.size()) {}
+ const android::String16& getInterfaceDescriptor() const override { return mDescriptor; }
+
+private:
+ android::String16 mDescriptor;
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ if (argc != 3) {
+ std::cerr << "usage: " << argv[0] << " <service-name> <interface-descriptor>" << std::endl;
+ return EX_USAGE;
+ }
+ auto name = argv[1];
+ auto descriptor = argv[2];
+
+ auto sm = android::defaultServiceManager();
+ CHECK(sm != nullptr);
+ auto service = android::sp<Service>::make(descriptor);
+ auto status = sm->addService(android::String16(name), service);
+ CHECK_EQ(android::OK, status) << android::statusToString(status);
+ std::cout << "running..." << std::endl;
+ android::ProcessState::self()->startThreadPool();
+ android::IPCThreadState::self()->joinThreadPool();
+ LOG(ERROR) << "joinThreadPool exits";
+ return EX_SOFTWARE;
+}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 5612d1d..4c3225f 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -15,25 +15,36 @@
*/
#include <errno.h>
-#include <fcntl.h>
-#include <fstream>
#include <poll.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
+
+#include <chrono>
+#include <fstream>
#include <thread>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <android-base/properties.h>
+#include <android-base/result-gmock.h>
+#include <android-base/result.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <binder/Binder.h>
+#include <binder/BpBinder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcSession.h>
#include <linux/sched.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include "../binder_module.h"
#include "binderAbiHelper.h"
@@ -41,7 +52,13 @@
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
using namespace android;
+using namespace std::string_literals;
+using namespace std::chrono_literals;
+using android::base::testing::HasValue;
+using android::base::testing::Ok;
+using testing::ExplainMatchResult;
using testing::Not;
+using testing::WithParamInterface;
// e.g. EXPECT_THAT(expr, StatusEq(OK)) << "additional message";
MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected)) {
@@ -72,6 +89,7 @@
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
BINDER_LIB_TEST_ADD_POLL_SERVER,
+ BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION,
BINDER_LIB_TEST_CALL_BACK,
BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
BINDER_LIB_TEST_DELAYED_CALL_BACK,
@@ -156,6 +174,20 @@
return pid;
}
+android::base::Result<int32_t> GetId(sp<IBinder> service) {
+ using android::base::Error;
+ Parcel data, reply;
+ data.markForBinder(service);
+ const char *prefix = data.isForRpc() ? "On RPC server, " : "On binder server, ";
+ status_t status = service->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
+ if (status != OK)
+ return Error(status) << prefix << "transact(GET_ID): " << statusToString(status);
+ int32_t result = 0;
+ status = reply.readInt32(&result);
+ if (status != OK) return Error(status) << prefix << "readInt32: " << statusToString(status);
+ return result;
+}
+
class BinderLibTestEnv : public ::testing::Environment {
public:
BinderLibTestEnv() {}
@@ -404,6 +436,14 @@
};
};
+TEST_F(BinderLibTest, WasParceled) {
+ auto binder = sp<BBinder>::make();
+ EXPECT_FALSE(binder->wasParceled());
+ Parcel data;
+ data.writeStrongBinder(binder);
+ EXPECT_TRUE(binder->wasParceled());
+}
+
TEST_F(BinderLibTest, NopTransaction) {
Parcel data, reply;
EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply),
@@ -475,12 +515,7 @@
}
TEST_F(BinderLibTest, GetId) {
- int32_t id;
- Parcel data, reply;
- EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply),
- StatusEq(NO_ERROR));
- EXPECT_THAT(reply.readInt32(&id), StatusEq(NO_ERROR));
- EXPECT_EQ(0, id);
+ EXPECT_THAT(GetId(m_server), HasValue(0));
}
TEST_F(BinderLibTest, PtrSize) {
@@ -603,6 +638,13 @@
EXPECT_THAT(callBack->getResult(), StatusEq(NO_ERROR));
}
+TEST_F(BinderLibTest, BinderCallContextGuard) {
+ sp<IBinder> binder = addServer();
+ Parcel data, reply;
+ EXPECT_THAT(binder->transact(BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION, data, &reply),
+ StatusEq(DEAD_OBJECT));
+}
+
TEST_F(BinderLibTest, AddServer)
{
sp<IBinder> server = addServer();
@@ -1134,39 +1176,116 @@
EXPECT_THAT(server->transact(BINDER_LIB_TEST_CAN_GET_SID, data, nullptr), StatusEq(OK));
}
-class BinderLibTestService : public BBinder
-{
- public:
- explicit BinderLibTestService(int32_t id)
- : m_id(id)
- , m_nextServerId(id + 1)
- , m_serverStartRequested(false)
- , m_callback(nullptr)
- {
- pthread_mutex_init(&m_serverWaitMutex, nullptr);
- pthread_cond_init(&m_serverWaitCond, nullptr);
+class BinderLibRpcTestBase : public BinderLibTest {
+public:
+ void SetUp() override {
+ if (!base::GetBoolProperty("ro.debuggable", false)) {
+ GTEST_SKIP() << "Binder RPC is only enabled on debuggable builds, skipping test on "
+ "non-debuggable builds.";
}
- ~BinderLibTestService()
- {
- exit(EXIT_SUCCESS);
- }
+ BinderLibTest::SetUp();
+ }
- void processPendingCall() {
- if (m_callback != nullptr) {
- Parcel data;
- data.writeInt32(NO_ERROR);
- m_callback->transact(BINDER_LIB_TEST_CALL_BACK, data, nullptr, TF_ONE_WAY);
- m_callback = nullptr;
- }
+ std::tuple<android::base::unique_fd, unsigned int> CreateSocket() {
+ auto rpcServer = RpcServer::make();
+ EXPECT_NE(nullptr, rpcServer);
+ if (rpcServer == nullptr) return {};
+ rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ unsigned int port;
+ if (!rpcServer->setupInetServer(0, &port)) {
+ ADD_FAILURE() << "setupInetServer failed";
+ return {};
}
+ return {rpcServer->releaseServer(), port};
+ }
+};
- virtual status_t onTransact(uint32_t code,
- const Parcel& data, Parcel* reply,
- uint32_t flags = 0) {
- if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
- return PERMISSION_DENIED;
- }
- switch (code) {
+class BinderLibRpcTest : public BinderLibRpcTestBase {};
+
+TEST_F(BinderLibRpcTest, SetRpcClientDebug) {
+ auto binder = addServer();
+ ASSERT_TRUE(binder != nullptr);
+ auto [socket, port] = CreateSocket();
+ ASSERT_TRUE(socket.ok());
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()), StatusEq(OK));
+}
+
+// Tests for multiple RpcServer's on the same binder object.
+TEST_F(BinderLibRpcTest, SetRpcClientDebugTwice) {
+ auto binder = addServer();
+ ASSERT_TRUE(binder != nullptr);
+
+ auto [socket1, port1] = CreateSocket();
+ ASSERT_TRUE(socket1.ok());
+ auto keepAliveBinder1 = sp<BBinder>::make();
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1), StatusEq(OK));
+
+ auto [socket2, port2] = CreateSocket();
+ ASSERT_TRUE(socket2.ok());
+ auto keepAliveBinder2 = sp<BBinder>::make();
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2), StatusEq(OK));
+}
+
+// Negative tests for RPC APIs on IBinder. Call should fail in the same way on both remote and
+// local binders.
+class BinderLibRpcTestP : public BinderLibRpcTestBase, public WithParamInterface<bool> {
+public:
+ sp<IBinder> GetService() {
+ return GetParam() ? sp<IBinder>(addServer()) : sp<IBinder>(sp<BBinder>::make());
+ }
+ static std::string ParamToString(const testing::TestParamInfo<ParamType> &info) {
+ return info.param ? "remote" : "local";
+ }
+};
+
+TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoFd) {
+ auto binder = GetService();
+ ASSERT_TRUE(binder != nullptr);
+ EXPECT_THAT(binder->setRpcClientDebug(android::base::unique_fd(), sp<BBinder>::make()),
+ StatusEq(BAD_VALUE));
+}
+
+TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoKeepAliveBinder) {
+ auto binder = GetService();
+ ASSERT_TRUE(binder != nullptr);
+ auto [socket, port] = CreateSocket();
+ ASSERT_TRUE(socket.ok());
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr), StatusEq(UNEXPECTED_NULL));
+}
+INSTANTIATE_TEST_CASE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
+ BinderLibRpcTestP::ParamToString);
+
+class BinderLibTestService : public BBinder {
+public:
+ explicit BinderLibTestService(int32_t id, bool exitOnDestroy = true)
+ : m_id(id),
+ m_nextServerId(id + 1),
+ m_serverStartRequested(false),
+ m_callback(nullptr),
+ m_exitOnDestroy(exitOnDestroy) {
+ pthread_mutex_init(&m_serverWaitMutex, nullptr);
+ pthread_cond_init(&m_serverWaitCond, nullptr);
+ }
+ ~BinderLibTestService() {
+ if (m_exitOnDestroy) exit(EXIT_SUCCESS);
+ }
+
+ void processPendingCall() {
+ if (m_callback != nullptr) {
+ Parcel data;
+ data.writeInt32(NO_ERROR);
+ m_callback->transact(BINDER_LIB_TEST_CALL_BACK, data, nullptr, TF_ONE_WAY);
+ m_callback = nullptr;
+ }
+ }
+
+ virtual status_t onTransact(uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0) {
+ // TODO(b/182914638): also checks getCallingUid() for RPC
+ if (!data.isForRpc() && getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
+ return PERMISSION_DENIED;
+ }
+ switch (code) {
case BINDER_LIB_TEST_REGISTER_SERVER: {
int32_t id;
sp<IBinder> binder;
@@ -1176,8 +1295,7 @@
return BAD_VALUE;
}
- if (m_id != 0)
- return INVALID_OPERATION;
+ if (m_id != 0) return INVALID_OPERATION;
pthread_mutex_lock(&m_serverWaitMutex);
if (m_serverStartRequested) {
@@ -1231,6 +1349,21 @@
pthread_mutex_unlock(&m_serverWaitMutex);
return ret;
}
+ case BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION: {
+ IPCThreadState::SpGuard spGuard{
+ .address = __builtin_frame_address(0),
+ .context = "GuardInBinderTransaction",
+ };
+ const IPCThreadState::SpGuard *origGuard =
+ IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);
+
+ // if the guard works, this should abort
+ (void)IPCThreadState::self()->getCallingPid();
+
+ IPCThreadState::self()->restoreGetCallingSpGuard(origGuard);
+ return NO_ERROR;
+ }
+
case BINDER_LIB_TEST_GETPID:
reply->writeInt32(getpid());
return NO_ERROR;
@@ -1347,8 +1480,7 @@
return BAD_VALUE;
}
ret = target->linkToDeath(testDeathRecipient);
- if (ret == NO_ERROR)
- ret = testDeathRecipient->waitEvent(5);
+ if (ret == NO_ERROR) ret = testDeathRecipient->waitEvent(5);
data2.writeInt32(ret);
callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
return NO_ERROR;
@@ -1372,8 +1504,7 @@
return BAD_VALUE;
}
ret = write(fd, buf, size);
- if (ret != size)
- return UNKNOWN_ERROR;
+ if (ret != size) return UNKNOWN_ERROR;
return NO_ERROR;
}
case BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION: {
@@ -1428,8 +1559,7 @@
case BINDER_LIB_TEST_ECHO_VECTOR: {
std::vector<uint64_t> vector;
auto err = data.readUint64Vector(&vector);
- if (err != NO_ERROR)
- return err;
+ if (err != NO_ERROR) return err;
reply->writeUint64Vector(vector);
return NO_ERROR;
}
@@ -1441,23 +1571,33 @@
}
default:
return UNKNOWN_TRANSACTION;
- };
- }
- private:
- int32_t m_id;
- int32_t m_nextServerId;
- pthread_mutex_t m_serverWaitMutex;
- pthread_cond_t m_serverWaitCond;
- bool m_serverStartRequested;
- sp<IBinder> m_serverStarted;
- sp<IBinder> m_strongRef;
- sp<IBinder> m_callback;
+ };
+ }
+
+private:
+ int32_t m_id;
+ int32_t m_nextServerId;
+ pthread_mutex_t m_serverWaitMutex;
+ pthread_cond_t m_serverWaitCond;
+ bool m_serverStartRequested;
+ sp<IBinder> m_serverStarted;
+ sp<IBinder> m_strongRef;
+ sp<IBinder> m_callback;
+ bool m_exitOnDestroy;
};
int run_server(int index, int readypipefd, bool usePoll)
{
binderLibTestServiceName += String16(binderserversuffix);
+ // Testing to make sure that calls that we are serving can use getCallin*
+ // even though we don't here.
+ IPCThreadState::SpGuard spGuard{
+ .address = __builtin_frame_address(0),
+ .context = "main server thread",
+ };
+ (void)IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);
+
status_t ret;
sp<IServiceManager> sm = defaultServiceManager();
BinderLibTestService* testServicePtr;
diff --git a/libs/binder/tests/binderParcelTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp
similarity index 100%
rename from libs/binder/tests/binderParcelTest.cpp
rename to libs/binder/tests/binderParcelUnitTest.cpp
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index a96deb5..40ebd9c 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <BnBinderRpcCallback.h>
#include <BnBinderRpcSession.h>
#include <BnBinderRpcTest.h>
#include <aidl/IBinderRpcTest.h>
@@ -23,6 +24,7 @@
#include <android/binder_libbinder.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/RpcServer.h>
@@ -33,6 +35,7 @@
#include <cstdlib>
#include <iostream>
#include <thread>
+#include <type_traits>
#include <sys/prctl.h>
#include <unistd.h>
@@ -40,6 +43,8 @@
#include "../RpcState.h" // for debugging
#include "../vm_sockets.h" // for VMADDR_*
+using namespace std::chrono_literals;
+
namespace android {
TEST(BinderRpcParcel, EntireParcelFormatted) {
@@ -86,6 +91,22 @@
};
std::atomic<int32_t> MyBinderRpcSession::gNum;
+class MyBinderRpcCallback : public BnBinderRpcCallback {
+ Status sendCallback(const std::string& value) {
+ std::unique_lock _l(mMutex);
+ mValues.push_back(value);
+ _l.unlock();
+ mCv.notify_one();
+ return Status::ok();
+ }
+ Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
+
+public:
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ std::vector<std::string> mValues;
+};
+
class MyBinderRpcTest : public BnBinderRpcTest {
public:
wp<RpcServer> server;
@@ -106,11 +127,6 @@
out->clear();
for (auto session : spServer->listSessions()) {
size_t count = session->state()->countBinders();
- if (count != 1) {
- // this is called when there is only one binder held remaining,
- // so to aid debugging
- session->state()->dump();
- }
out->push_back(count);
}
return Status::ok();
@@ -184,6 +200,33 @@
return sleepMs(ms);
}
+ Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
+ const std::string& value) override {
+ if (callback == nullptr) {
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+ }
+
+ if (delayed) {
+ std::thread([=]() {
+ ALOGE("Executing delayed callback: '%s'", value.c_str());
+ Status status = doCallback(callback, oneway, false, value);
+ ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
+ }).detach();
+ return Status::ok();
+ }
+
+ if (oneway) {
+ return callback->sendOnewayCallback(value);
+ }
+
+ return callback->sendCallback(value);
+ }
+
+ Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
+ const std::string& value) override {
+ return doCallback(callback, oneway, delayed, value);
+ }
+
Status die(bool cleanup) override {
if (cleanup) {
exit(1);
@@ -191,42 +234,53 @@
_exit(1);
}
}
+
+ Status scheduleShutdown() override {
+ sp<RpcServer> strongServer = server.promote();
+ if (strongServer == nullptr) {
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+ }
+ std::thread([=] {
+ LOG_ALWAYS_FATAL_IF(!strongServer->shutdown(), "Could not shutdown");
+ }).detach();
+ return Status::ok();
+ }
+
+ Status useKernelBinderCallingId() override {
+ // this is WRONG! It does not make sense when using RPC binder, and
+ // because it is SO wrong, and so much code calls this, it should abort!
+
+ (void)IPCThreadState::self()->getCallingPid();
+ return Status::ok();
+ }
};
sp<IBinder> MyBinderRpcTest::mHeldBinder;
-class Pipe {
-public:
- Pipe() { CHECK(android::base::Pipe(&mRead, &mWrite)); }
- Pipe(Pipe&&) = default;
- android::base::borrowed_fd readEnd() { return mRead; }
- android::base::borrowed_fd writeEnd() { return mWrite; }
-
-private:
- android::base::unique_fd mRead;
- android::base::unique_fd mWrite;
-};
-
class Process {
public:
Process(Process&&) = default;
- Process(const std::function<void(Pipe*)>& f) {
+ Process(const std::function<void(android::base::borrowed_fd /* writeEnd */)>& f) {
+ android::base::unique_fd writeEnd;
+ CHECK(android::base::Pipe(&mReadEnd, &writeEnd)) << strerror(errno);
if (0 == (mPid = fork())) {
// racey: assume parent doesn't crash before this is set
prctl(PR_SET_PDEATHSIG, SIGHUP);
- f(&mPipe);
+ f(writeEnd);
+
+ exit(0);
}
}
~Process() {
if (mPid != 0) {
- kill(mPid, SIGKILL);
+ waitpid(mPid, nullptr, 0);
}
}
- Pipe* getPipe() { return &mPipe; }
+ android::base::borrowed_fd readEnd() { return mReadEnd; }
private:
pid_t mPid = 0;
- Pipe mPipe;
+ android::base::unique_fd mReadEnd;
};
static std::string allocateSocketAddress() {
@@ -235,6 +289,11 @@
return temp + "/binderRpcTest_" + std::to_string(id++);
};
+static unsigned int allocateVsockPort() {
+ static unsigned int vsockPort = 3456;
+ return vsockPort++;
+}
+
struct ProcessSession {
// reference to process hosting a socket server
Process host;
@@ -280,11 +339,14 @@
sp<IBinderRpcTest> rootIface;
// whether session should be invalidated by end of run
- bool expectInvalid = false;
+ bool expectAlreadyShutdown = false;
BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default;
~BinderRpcTestProcessSession() {
- if (!expectInvalid) {
+ EXPECT_NE(nullptr, rootIface);
+ if (rootIface == nullptr) return;
+
+ if (!expectAlreadyShutdown) {
std::vector<int32_t> remoteCounts;
// calling over any sessions counts across all sessions
EXPECT_OK(rootIface->countBinders(&remoteCounts));
@@ -292,6 +354,12 @@
for (auto remoteCount : remoteCounts) {
EXPECT_EQ(remoteCount, 1);
}
+
+ // even though it is on another thread, shutdown races with
+ // the transaction reply being written
+ if (auto status = rootIface->scheduleShutdown(); !status.isOk()) {
+ EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+ }
}
rootIface = nullptr;
@@ -317,28 +385,33 @@
return "";
}
}
+
class BinderRpc : public ::testing::TestWithParam<SocketType> {
public:
+ struct Options {
+ size_t numThreads = 1;
+ size_t numSessions = 1;
+ size_t numIncomingConnections = 0;
+ };
+
// This creates a new process serving an interface on a certain number of
// threads.
ProcessSession createRpcTestSocketServerProcess(
- size_t numThreads, size_t numSessions,
- const std::function<void(const sp<RpcServer>&)>& configure) {
- CHECK_GE(numSessions, 1) << "Must have at least one session to a server";
+ const Options& options, const std::function<void(const sp<RpcServer>&)>& configure) {
+ CHECK_GE(options.numSessions, 1) << "Must have at least one session to a server";
SocketType socketType = GetParam();
+ unsigned int vsockPort = allocateVsockPort();
std::string addr = allocateSocketAddress();
unlink(addr.c_str());
- static unsigned int vsockPort = 3456;
- vsockPort++;
auto ret = ProcessSession{
- .host = Process([&](Pipe* pipe) {
+ .host = Process([&](android::base::borrowed_fd writeEnd) {
sp<RpcServer> server = RpcServer::make();
server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
- server->setMaxThreads(numThreads);
+ server->setMaxThreads(options.numThreads);
unsigned int outPort = 0;
@@ -358,23 +431,28 @@
LOG_ALWAYS_FATAL("Unknown socket type");
}
- CHECK(android::base::WriteFully(pipe->writeEnd(), &outPort, sizeof(outPort)));
+ CHECK(android::base::WriteFully(writeEnd, &outPort, sizeof(outPort)));
configure(server);
server->join();
+
+ // Another thread calls shutdown. Wait for it to complete.
+ (void)server->shutdown();
}),
};
// always read socket, so that we have waited for the server to start
unsigned int outPort = 0;
- CHECK(android::base::ReadFully(ret.host.getPipe()->readEnd(), &outPort, sizeof(outPort)));
+ CHECK(android::base::ReadFully(ret.host.readEnd(), &outPort, sizeof(outPort)));
if (socketType == SocketType::INET) {
CHECK_NE(0, outPort);
}
- for (size_t i = 0; i < numSessions; i++) {
+ for (size_t i = 0; i < options.numSessions; i++) {
sp<RpcSession> session = RpcSession::make();
+ session->setMaxThreads(options.numIncomingConnections);
+
switch (socketType) {
case SocketType::UNIX:
if (session->setupUnixDomainClient(addr.c_str())) goto success;
@@ -395,10 +473,9 @@
return ret;
}
- BinderRpcTestProcessSession createRpcTestSocketServerProcess(size_t numThreads,
- size_t numSessions = 1) {
+ BinderRpcTestProcessSession createRpcTestSocketServerProcess(const Options& options) {
BinderRpcTestProcessSession ret{
- .proc = createRpcTestSocketServerProcess(numThreads, numSessions,
+ .proc = createRpcTestSocketServerProcess(options,
[&](const sp<RpcServer>& server) {
sp<MyBinderRpcTest> service =
new MyBinderRpcTest;
@@ -414,29 +491,20 @@
}
};
-TEST_P(BinderRpc, RootObjectIsNull) {
- auto proc = createRpcTestSocketServerProcess(1, 1, [](const sp<RpcServer>& server) {
- // this is the default, but to be explicit
- server->setRootObject(nullptr);
- });
-
- EXPECT_EQ(nullptr, proc.sessions.at(0).root);
-}
-
TEST_P(BinderRpc, Ping) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
ASSERT_NE(proc.rootBinder, nullptr);
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
}
TEST_P(BinderRpc, GetInterfaceDescriptor) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
ASSERT_NE(proc.rootBinder, nullptr);
EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor());
}
TEST_P(BinderRpc, MultipleSessions) {
- auto proc = createRpcTestSocketServerProcess(1 /*threads*/, 5 /*sessions*/);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 5});
for (auto session : proc.proc.sessions) {
ASSERT_NE(nullptr, session.root);
EXPECT_EQ(OK, session.root->pingBinder());
@@ -444,14 +512,14 @@
}
TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
Parcel data;
Parcel reply;
EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
}
TEST_P(BinderRpc, AppendSeparateFormats) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
Parcel p1;
p1.markForBinder(proc.rootBinder);
@@ -464,7 +532,7 @@
}
TEST_P(BinderRpc, UnknownTransaction) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
Parcel data;
data.markForBinder(proc.rootBinder);
Parcel reply;
@@ -472,19 +540,19 @@
}
TEST_P(BinderRpc, SendSomethingOneway) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
EXPECT_OK(proc.rootIface->sendString("asdf"));
}
TEST_P(BinderRpc, SendAndGetResultBack) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
std::string doubled;
EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
EXPECT_EQ("cool cool ", doubled);
}
TEST_P(BinderRpc, SendAndGetResultBackBig) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
std::string single = std::string(1024, 'a');
std::string doubled;
EXPECT_OK(proc.rootIface->doubleString(single, &doubled));
@@ -492,7 +560,7 @@
}
TEST_P(BinderRpc, CallMeBack) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
int32_t pingResult;
EXPECT_OK(proc.rootIface->pingMe(new MyBinderRpcSession("foo"), &pingResult));
@@ -502,7 +570,7 @@
}
TEST_P(BinderRpc, RepeatBinder) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> inBinder = new MyBinderRpcSession("foo");
sp<IBinder> outBinder;
@@ -524,7 +592,7 @@
}
TEST_P(BinderRpc, RepeatTheirBinder) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinderRpcSession> session;
EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
@@ -548,7 +616,7 @@
}
TEST_P(BinderRpc, RepeatBinderNull) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> outBinder;
EXPECT_OK(proc.rootIface->repeatBinder(nullptr, &outBinder));
@@ -556,7 +624,7 @@
}
TEST_P(BinderRpc, HoldBinder) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
IBinder* ptr = nullptr;
{
@@ -582,8 +650,8 @@
// aren't supported.
TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketSessions) {
- auto proc1 = createRpcTestSocketServerProcess(1);
- auto proc2 = createRpcTestSocketServerProcess(1);
+ auto proc1 = createRpcTestSocketServerProcess({});
+ auto proc2 = createRpcTestSocketServerProcess({});
sp<IBinder> outBinder;
EXPECT_EQ(INVALID_OPERATION,
@@ -591,7 +659,7 @@
}
TEST_P(BinderRpc, CannotMixBindersBetweenTwoSessionsToTheSameServer) {
- auto proc = createRpcTestSocketServerProcess(1 /*threads*/, 2 /*sessions*/);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 2});
sp<IBinder> outBinder;
EXPECT_EQ(INVALID_OPERATION,
@@ -600,7 +668,7 @@
}
TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
sp<IBinder> outBinder;
@@ -609,7 +677,7 @@
}
TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
// for historical reasons, IServiceManager interface only returns the
// exception code
@@ -620,7 +688,7 @@
// END TESTS FOR LIMITATIONS OF SOCKET BINDER
TEST_P(BinderRpc, RepeatRootObject) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> outBinder;
EXPECT_OK(proc.rootIface->repeatBinder(proc.rootBinder, &outBinder));
@@ -628,7 +696,7 @@
}
TEST_P(BinderRpc, NestedTransactions) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
auto nastyNester = sp<MyBinderRpcTest>::make();
EXPECT_OK(proc.rootIface->nestMe(nastyNester, 10));
@@ -639,7 +707,7 @@
}
TEST_P(BinderRpc, SameBinderEquality) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> a;
EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
@@ -651,7 +719,7 @@
}
TEST_P(BinderRpc, SameBinderEqualityWeak) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinder> a;
EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
@@ -683,7 +751,7 @@
} while (false)
TEST_P(BinderRpc, SingleSession) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
sp<IBinderRpcSession> session;
EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
@@ -697,7 +765,7 @@
}
TEST_P(BinderRpc, ManySessions) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
std::vector<sp<IBinderRpcSession>> sessions;
@@ -733,7 +801,7 @@
TEST_P(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
constexpr size_t kNumThreads = 10;
- auto proc = createRpcTestSocketServerProcess(kNumThreads);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
EXPECT_OK(proc.rootIface->lock());
@@ -767,7 +835,7 @@
constexpr size_t kNumCalls = kNumThreads + 3;
constexpr size_t kSleepMs = 500;
- auto proc = createRpcTestSocketServerProcess(kNumThreads);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
size_t epochMsBefore = epochMillis();
@@ -791,7 +859,7 @@
constexpr size_t kNumServerThreads = 10;
constexpr size_t kNumCalls = 100;
- auto proc = createRpcTestSocketServerProcess(kNumServerThreads);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = kNumServerThreads});
std::vector<std::thread> threads;
for (size_t i = 0; i < kNumClientThreads; i++) {
@@ -810,9 +878,9 @@
TEST_P(BinderRpc, OnewayStressTest) {
constexpr size_t kNumClientThreads = 10;
constexpr size_t kNumServerThreads = 10;
- constexpr size_t kNumCalls = 100;
+ constexpr size_t kNumCalls = 500;
- auto proc = createRpcTestSocketServerProcess(kNumServerThreads);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = kNumServerThreads});
std::vector<std::thread> threads;
for (size_t i = 0; i < kNumClientThreads; i++) {
@@ -833,8 +901,7 @@
constexpr size_t kReallyLongTimeMs = 100;
constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
- // more than one thread, just so this doesn't deadlock
- auto proc = createRpcTestSocketServerProcess(2);
+ auto proc = createRpcTestSocketServerProcess({});
size_t epochMsBefore = epochMillis();
@@ -850,7 +917,7 @@
constexpr size_t kSleepMs = 50;
// make sure calls to the same object happen on the same thread
- auto proc = createRpcTestSocketServerProcess(1 + kNumExtraServerThreads);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = 1 + kNumExtraServerThreads});
EXPECT_OK(proc.rootIface->lock());
@@ -866,11 +933,113 @@
size_t epochMsAfter = epochMillis();
EXPECT_GT(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);
+
+ // pending oneway transactions hold ref, make sure we read data on all
+ // sockets
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < 1 + kNumExtraServerThreads; i++) {
+ threads.push_back(std::thread([&] { EXPECT_OK(proc.rootIface->sleepMs(250)); }));
+ }
+ for (auto& t : threads) t.join();
+}
+
+TEST_P(BinderRpc, OnewayCallExhaustion) {
+ constexpr size_t kNumClients = 2;
+ constexpr size_t kTooLongMs = 1000;
+
+ auto proc = createRpcTestSocketServerProcess({.numThreads = kNumClients, .numSessions = 2});
+
+ // Build up oneway calls on the second session to make sure it terminates
+ // and shuts down. The first session should be unaffected (proc destructor
+ // checks the first session).
+ auto iface = interface_cast<IBinderRpcTest>(proc.proc.sessions.at(1).root);
+
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < kNumClients; i++) {
+ // one of these threads will get stuck queueing a transaction once the
+ // socket fills up, the other will be able to fill up transactions on
+ // this object
+ threads.push_back(std::thread([&] {
+ while (iface->sleepMsAsync(kTooLongMs).isOk()) {
+ }
+ }));
+ }
+ for (auto& t : threads) t.join();
+
+ Status status = iface->sleepMsAsync(kTooLongMs);
+ EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+
+ // now that it has died, wait for the remote session to shutdown
+ std::vector<int32_t> remoteCounts;
+ do {
+ EXPECT_OK(proc.rootIface->countBinders(&remoteCounts));
+ } while (remoteCounts.size() == kNumClients);
+
+ // the second session should be shutdown in the other process by the time we
+ // are able to join above (it'll only be hung up once it finishes processing
+ // any pending commands). We need to erase this session from the record
+ // here, so that the destructor for our session won't check that this
+ // session is valid, but we still want it to test the other session.
+ proc.proc.sessions.erase(proc.proc.sessions.begin() + 1);
+}
+
+TEST_P(BinderRpc, Callbacks) {
+ const static std::string kTestString = "good afternoon!";
+
+ for (bool callIsOneway : {true, false}) {
+ for (bool callbackIsOneway : {true, false}) {
+ for (bool delayed : {true, false}) {
+ auto proc = createRpcTestSocketServerProcess(
+ {.numThreads = 1, .numSessions = 1, .numIncomingConnections = 1});
+ auto cb = sp<MyBinderRpcCallback>::make();
+
+ if (callIsOneway) {
+ EXPECT_OK(proc.rootIface->doCallbackAsync(cb, callbackIsOneway, delayed,
+ kTestString));
+ } else {
+ EXPECT_OK(
+ proc.rootIface->doCallback(cb, callbackIsOneway, delayed, kTestString));
+ }
+
+ using std::literals::chrono_literals::operator""s;
+ std::unique_lock<std::mutex> _l(cb->mMutex);
+ cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); });
+
+ EXPECT_EQ(cb->mValues.size(), 1)
+ << "callIsOneway: " << callIsOneway
+ << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+ if (cb->mValues.empty()) continue;
+ EXPECT_EQ(cb->mValues.at(0), kTestString)
+ << "callIsOneway: " << callIsOneway
+ << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+
+ // since we are severing the connection, we need to go ahead and
+ // tell the server to shutdown and exit so that waitpid won't hang
+ if (auto status = proc.rootIface->scheduleShutdown(); !status.isOk()) {
+ EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+ }
+
+ // since this session has an incoming connection w/ a threadpool, we
+ // need to manually shut it down
+ EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
+
+ proc.expectAlreadyShutdown = true;
+ }
+ }
+ }
+}
+
+TEST_P(BinderRpc, OnewayCallbackWithNoThread) {
+ auto proc = createRpcTestSocketServerProcess({});
+ auto cb = sp<MyBinderRpcCallback>::make();
+
+ Status status = proc.rootIface->doCallback(cb, true /*oneway*/, false /*delayed*/, "anything");
+ EXPECT_EQ(WOULD_BLOCK, status.transactionError());
}
TEST_P(BinderRpc, Die) {
for (bool doDeathCleanup : {true, false}) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
// make sure there is some state during crash
// 1. we hold their binder
@@ -883,12 +1052,25 @@
EXPECT_EQ(DEAD_OBJECT, proc.rootIface->die(doDeathCleanup).transactionError())
<< "Do death cleanup: " << doDeathCleanup;
- proc.expectInvalid = true;
+ proc.expectAlreadyShutdown = true;
}
}
+TEST_P(BinderRpc, UseKernelBinderCallingId) {
+ auto proc = createRpcTestSocketServerProcess({});
+
+ // we can't allocate IPCThreadState so actually the first time should
+ // succeed :(
+ EXPECT_OK(proc.rootIface->useKernelBinderCallingId());
+
+ // second time! we catch the error :)
+ EXPECT_EQ(DEAD_OBJECT, proc.rootIface->useKernelBinderCallingId().transactionError());
+
+ proc.expectAlreadyShutdown = true;
+}
+
TEST_P(BinderRpc, WorksWithLibbinderNdkPing) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
ASSERT_NE(binder, nullptr);
@@ -897,7 +1079,7 @@
}
TEST_P(BinderRpc, WorksWithLibbinderNdkUserTransaction) {
- auto proc = createRpcTestSocketServerProcess(1);
+ auto proc = createRpcTestSocketServerProcess({});
ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
ASSERT_NE(binder, nullptr);
@@ -925,21 +1107,39 @@
ssize_t beforeFds = countFds();
ASSERT_GE(beforeFds, 0);
{
- auto proc = createRpcTestSocketServerProcess(10);
+ auto proc = createRpcTestSocketServerProcess({.numThreads = 10});
ASSERT_EQ(OK, proc.rootBinder->pingBinder());
}
ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
}
-INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
- ::testing::ValuesIn({
- SocketType::UNIX,
-// TODO(b/185269356): working on host
-#ifdef __BIONIC__
- SocketType::VSOCK,
-#endif
- SocketType::INET,
- }),
+static bool testSupportVsockLoopback() {
+ unsigned int vsockPort = allocateVsockPort();
+ sp<RpcServer> server = RpcServer::make();
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ CHECK(server->setupVsockServer(vsockPort));
+ server->start();
+
+ sp<RpcSession> session = RpcSession::make();
+ bool okay = session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort);
+ while (!server->shutdown()) usleep(10000);
+ ALOGE("Detected vsock loopback supported: %d", okay);
+ return okay;
+}
+
+static std::vector<SocketType> testSocketTypes() {
+ std::vector<SocketType> ret = {SocketType::UNIX, SocketType::INET};
+
+ static bool hasVsockLoopback = testSupportVsockLoopback();
+
+ if (hasVsockLoopback) {
+ ret.push_back(SocketType::VSOCK);
+ }
+
+ return ret;
+}
+
+INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc, ::testing::ValuesIn(testSocketTypes()),
PrintSocketType);
class BinderRpcServerRootObject : public ::testing::TestWithParam<std::tuple<bool, bool>> {};
@@ -970,6 +1170,91 @@
INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerRootObject,
::testing::Combine(::testing::Bool(), ::testing::Bool()));
+class OneOffSignal {
+public:
+ // If notify() was previously called, or is called within |duration|, return true; else false.
+ template <typename R, typename P>
+ bool wait(std::chrono::duration<R, P> duration) {
+ std::unique_lock<std::mutex> lock(mMutex);
+ return mCv.wait_for(lock, duration, [this] { return mValue; });
+ }
+ void notify() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mValue = true;
+ lock.unlock();
+ mCv.notify_all();
+ }
+
+private:
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ bool mValue = false;
+};
+
+TEST(BinderRpc, Shutdown) {
+ auto addr = allocateSocketAddress();
+ unlink(addr.c_str());
+ auto server = RpcServer::make();
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ ASSERT_TRUE(server->setupUnixDomainServer(addr.c_str()));
+ auto joinEnds = std::make_shared<OneOffSignal>();
+
+ // If things are broken and the thread never stops, don't block other tests. Because the thread
+ // may run after the test finishes, it must not access the stack memory of the test. Hence,
+ // shared pointers are passed.
+ std::thread([server, joinEnds] {
+ server->join();
+ joinEnds->notify();
+ }).detach();
+
+ bool shutdown = false;
+ for (int i = 0; i < 10 && !shutdown; i++) {
+ usleep(300 * 1000); // 300ms; total 3s
+ if (server->shutdown()) shutdown = true;
+ }
+ ASSERT_TRUE(shutdown) << "server->shutdown() never returns true";
+
+ ASSERT_TRUE(joinEnds->wait(2s))
+ << "After server->shutdown() returns true, join() did not stop after 2s";
+}
+
+TEST(BinderRpc, Java) {
+#if !defined(__ANDROID__)
+ GTEST_SKIP() << "This test is only run on Android. Though it can technically run on host on"
+ "createRpcDelegateServiceManager() with a device attached, such test belongs "
+ "to binderHostDeviceTest. Hence, just disable this test on host.";
+#endif // !__ANDROID__
+ sp<IServiceManager> sm = defaultServiceManager();
+ ASSERT_NE(nullptr, sm);
+ // Any Java service with non-empty getInterfaceDescriptor() would do.
+ // Let's pick batteryproperties.
+ auto binder = sm->checkService(String16("batteryproperties"));
+ ASSERT_NE(nullptr, binder);
+ auto descriptor = binder->getInterfaceDescriptor();
+ ASSERT_GE(descriptor.size(), 0);
+ ASSERT_EQ(OK, binder->pingBinder());
+
+ auto rpcServer = RpcServer::make();
+ rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+ unsigned int port;
+ ASSERT_TRUE(rpcServer->setupInetServer(0, &port));
+ auto socket = rpcServer->releaseServer();
+
+ auto keepAlive = sp<BBinder>::make();
+ ASSERT_EQ(OK, binder->setRpcClientDebug(std::move(socket), keepAlive));
+
+ auto rpcSession = RpcSession::make();
+ ASSERT_TRUE(rpcSession->setupInetClient("127.0.0.1", port));
+ auto rpcBinder = rpcSession->getRootObject();
+ ASSERT_NE(nullptr, rpcBinder);
+
+ ASSERT_EQ(OK, rpcBinder->pingBinder());
+
+ ASSERT_EQ(descriptor, rpcBinder->getInterfaceDescriptor())
+ << "getInterfaceDescriptor should not crash system_server";
+ ASSERT_EQ(OK, rpcBinder->pingBinder());
+}
+
} // namespace android
int main(int argc, char** argv) {
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 2ce13df..6c3b3d9 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -102,7 +102,7 @@
return Status::ok();
}
Status sendAndCallBinder(const sp<IBinder>& binder) override {
- Stability::debugLogStability("sendAndCallBinder got binder", binder);
+ ALOGI("Debug log stability: %s", Stability::debugToString(binder).c_str());
return Status::fromExceptionCode(BadStableBinder::doUserTransaction(binder));
}
Status returnNoStabilityBinder(sp<IBinder>* _aidl_return) override {
diff --git a/libs/binder/tests/binderUtilsHostTest.cpp b/libs/binder/tests/binderUtilsHostTest.cpp
new file mode 100644
index 0000000..fb24836
--- /dev/null
+++ b/libs/binder/tests/binderUtilsHostTest.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 <sysexits.h>
+
+#include <chrono>
+
+#include <android-base/result-gmock.h>
+#include <android-base/strings.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "../UtilsHost.h"
+
+using android::base::testing::Ok;
+using testing::Optional;
+
+namespace android {
+
+TEST(UtilsHost, ExecuteImmediately) {
+ auto result = execute({"echo", "foo"}, nullptr);
+ ASSERT_THAT(result, Ok());
+ EXPECT_THAT(result->exitCode, Optional(EX_OK));
+ EXPECT_EQ(result->stdout, "foo\n");
+}
+
+TEST(UtilsHost, ExecuteLongRunning) {
+ auto now = std::chrono::system_clock::now();
+
+ {
+ std::vector<std::string> args{"sh", "-c",
+ "sleep 0.5 && echo -n f && sleep 0.5 && echo oo && sleep 1"};
+ auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+ return android::base::EndsWith(commandResult.stdout, "\n");
+ });
+ auto elapsed = std::chrono::system_clock::now() - now;
+ auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+ EXPECT_GE(elapsedMs, 1000);
+ EXPECT_LT(elapsedMs, 2000);
+
+ ASSERT_THAT(result, Ok());
+ EXPECT_EQ(std::nullopt, result->exitCode);
+ EXPECT_EQ(result->stdout, "foo\n");
+ }
+
+ // ~CommandResult() called, child process is killed.
+ // Assert that the second sleep does not finish.
+ auto elapsed = std::chrono::system_clock::now() - now;
+ auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+ EXPECT_LT(elapsedMs, 2000);
+}
+
+TEST(UtilsHost, ExecuteLongRunning2) {
+ auto now = std::chrono::system_clock::now();
+
+ {
+ std::vector<std::string> args{"sh", "-c",
+ "sleep 2 && echo -n f && sleep 2 && echo oo && sleep 2"};
+ auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+ return android::base::EndsWith(commandResult.stdout, "\n");
+ });
+ auto elapsed = std::chrono::system_clock::now() - now;
+ auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+ EXPECT_GE(elapsedMs, 4000);
+ EXPECT_LT(elapsedMs, 6000);
+
+ ASSERT_THAT(result, Ok());
+ EXPECT_EQ(std::nullopt, result->exitCode);
+ EXPECT_EQ(result->stdout, "foo\n");
+ }
+
+ // ~CommandResult() called, child process is killed.
+ // Assert that the second sleep does not finish.
+ auto elapsed = std::chrono::system_clock::now() - now;
+ auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+ EXPECT_LT(elapsedMs, 6000);
+}
+
+TEST(UtilsHost, KillWithSigKill) {
+ std::vector<std::string> args{"sh", "-c", "echo foo && sleep 10"};
+ auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+ // FOR TEST PURPOSE ONLY. DON'T DO THIS!
+ if (commandResult.pid.has_value()) {
+ (void)kill(*commandResult.pid, SIGKILL);
+ }
+ // FOR TEST PURPOSE ONLY. DON'T DO THIS!
+ return false;
+ });
+
+ ASSERT_THAT(result, Ok());
+ EXPECT_EQ(std::nullopt, result->exitCode);
+ EXPECT_THAT(result->signal, Optional(SIGKILL));
+}
+
+} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 624def1..a717ce9 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -66,6 +66,10 @@
int32_t mValue = 0;
};
+struct BigStruct {
+ uint8_t data[1337];
+};
+
#define PARCEL_READ_WITH_STATUS(T, FUN) \
[] (const ::android::Parcel& p, uint8_t /*data*/) {\
FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
@@ -165,22 +169,20 @@
PARCEL_READ_WITH_STATUS(android::sp<android::IBinder>, readStrongBinder),
PARCEL_READ_WITH_STATUS(android::sp<android::IBinder>, readNullableStrongBinder),
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // PARCEL_READ_WITH_STATUS(std::vector<ByteEnum>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<ByteEnum>>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<ByteEnum>>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::vector<IntEnum>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<IntEnum>>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<IntEnum>>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::vector<LongEnum>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<LongEnum>>, readEnumVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<LongEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::vector<ByteEnum>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<ByteEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<ByteEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::vector<IntEnum>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<IntEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<IntEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::vector<LongEnum>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<LongEnum>>, readEnumVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<LongEnum>>, readEnumVector),
// only reading one parcelable type for now
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<ExampleParcelable>>>, readParcelableVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<ExampleParcelable>>>, readParcelableVector),
- // PARCEL_READ_WITH_STATUS(std::vector<ExampleParcelable>, readParcelableVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<ExampleParcelable>>>, readParcelableVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<ExampleParcelable>>>, readParcelableVector),
+ PARCEL_READ_WITH_STATUS(std::vector<ExampleParcelable>, readParcelableVector),
PARCEL_READ_WITH_STATUS(ExampleParcelable, readParcelable),
PARCEL_READ_WITH_STATUS(std::unique_ptr<ExampleParcelable>, readParcelable),
PARCEL_READ_WITH_STATUS(std::optional<ExampleParcelable>, readParcelable),
@@ -189,45 +191,43 @@
PARCEL_READ_WITH_STATUS(android::sp<android::os::IServiceManager>, readStrongBinder),
PARCEL_READ_WITH_STATUS(android::sp<android::os::IServiceManager>, readNullableStrongBinder),
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // PARCEL_READ_WITH_STATUS(::std::unique_ptr<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
- // PARCEL_READ_WITH_STATUS(::std::optional<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
- // PARCEL_READ_WITH_STATUS(std::vector<android::sp<android::IBinder>>, readStrongBinderVector),
+ PARCEL_READ_WITH_STATUS(::std::unique_ptr<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
+ PARCEL_READ_WITH_STATUS(::std::optional<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
+ PARCEL_READ_WITH_STATUS(std::vector<android::sp<android::IBinder>>, readStrongBinderVector),
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int8_t>>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int8_t>>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::vector<int8_t>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, readByteVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int32_t>>, readInt32Vector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int32_t>>, readInt32Vector),
- // PARCEL_READ_WITH_STATUS(std::vector<int32_t>, readInt32Vector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int64_t>>, readInt64Vector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int64_t>>, readInt64Vector),
- // PARCEL_READ_WITH_STATUS(std::vector<int64_t>, readInt64Vector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint64_t>>, readUint64Vector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint64_t>>, readUint64Vector),
- // PARCEL_READ_WITH_STATUS(std::vector<uint64_t>, readUint64Vector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<float>>, readFloatVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<float>>, readFloatVector),
- // PARCEL_READ_WITH_STATUS(std::vector<float>, readFloatVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<double>>, readDoubleVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<double>>, readDoubleVector),
- // PARCEL_READ_WITH_STATUS(std::vector<double>, readDoubleVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<bool>>, readBoolVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<bool>>, readBoolVector),
- // PARCEL_READ_WITH_STATUS(std::vector<bool>, readBoolVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<char16_t>>, readCharVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<char16_t>>, readCharVector),
- // PARCEL_READ_WITH_STATUS(std::vector<char16_t>, readCharVector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<android::String16>>>, readString16Vector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<android::String16>>>, readString16Vector),
- // PARCEL_READ_WITH_STATUS(std::vector<android::String16>, readString16Vector),
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<std::string>>>, readUtf8VectorFromUtf16Vector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<std::string>>>, readUtf8VectorFromUtf16Vector),
- // PARCEL_READ_WITH_STATUS(std::vector<std::string>, readUtf8VectorFromUtf16Vector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int8_t>>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<int8_t>>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::vector<int8_t>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, readByteVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int32_t>>, readInt32Vector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<int32_t>>, readInt32Vector),
+ PARCEL_READ_WITH_STATUS(std::vector<int32_t>, readInt32Vector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int64_t>>, readInt64Vector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<int64_t>>, readInt64Vector),
+ PARCEL_READ_WITH_STATUS(std::vector<int64_t>, readInt64Vector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint64_t>>, readUint64Vector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint64_t>>, readUint64Vector),
+ PARCEL_READ_WITH_STATUS(std::vector<uint64_t>, readUint64Vector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<float>>, readFloatVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<float>>, readFloatVector),
+ PARCEL_READ_WITH_STATUS(std::vector<float>, readFloatVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<double>>, readDoubleVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<double>>, readDoubleVector),
+ PARCEL_READ_WITH_STATUS(std::vector<double>, readDoubleVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<bool>>, readBoolVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<bool>>, readBoolVector),
+ PARCEL_READ_WITH_STATUS(std::vector<bool>, readBoolVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<char16_t>>, readCharVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<char16_t>>, readCharVector),
+ PARCEL_READ_WITH_STATUS(std::vector<char16_t>, readCharVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<android::String16>>>, readString16Vector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<android::String16>>>, readString16Vector),
+ PARCEL_READ_WITH_STATUS(std::vector<android::String16>, readString16Vector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<std::string>>>, readUtf8VectorFromUtf16Vector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<std::string>>>, readUtf8VectorFromUtf16Vector),
+ PARCEL_READ_WITH_STATUS(std::vector<std::string>, readUtf8VectorFromUtf16Vector),
[] (const android::Parcel& p, uint8_t /*len*/) {
FUZZ_LOG() << "about to read flattenable";
@@ -242,8 +242,12 @@
FUZZ_LOG() << "read lite flattenable: " << status;
},
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // TODO: resizeOutVector
+ PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, resizeOutVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, resizeOutVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, resizeOutVector),
+ PARCEL_READ_WITH_STATUS(std::vector<BigStruct>, resizeOutVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<BigStruct>>, resizeOutVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),
PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
[] (const android::Parcel& p, uint8_t /*len*/) {
@@ -261,10 +265,9 @@
PARCEL_READ_NO_STATUS(int, readParcelFileDescriptor),
PARCEL_READ_WITH_STATUS(android::base::unique_fd, readUniqueFileDescriptor),
- // TODO(b/131868573): can force read of arbitrarily sized vector
- // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
- // PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
- // PARCEL_READ_WITH_STATUS(std::vector<android::base::unique_fd>, readUniqueFileDescriptorVector),
+ PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
+ PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
+ PARCEL_READ_WITH_STATUS(std::vector<android::base::unique_fd>, readUniqueFileDescriptorVector),
[] (const android::Parcel& p, uint8_t len) {
FUZZ_LOG() << "about to readBlob";
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index 008780c..6b783a4 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -91,28 +91,27 @@
PARCEL_READ(ndk::ScopedFileDescriptor, ndk::AParcel_readRequiredParcelFileDescriptor),
PARCEL_READ(std::string, ndk::AParcel_readString),
PARCEL_READ(std::optional<std::string>, ndk::AParcel_readString),
- // TODO(b/131868573): can force process to allocate arbitrary amount of
- // memory
- // PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>,
- // ndk::AParcel_readVector), PARCEL_READ(std::vector<SomeParcelable>,
- // ndk::AParcel_readVector), PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
- // PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
- // PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
- // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
+
+ PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<SomeParcelable>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
+ PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
+ PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
+ PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
};
// clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
index 0fec393..35b5ebc 100644
--- a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
@@ -148,28 +148,6 @@
// should be null since we don't create any IPC objects
CHECK(data == nullptr) << data;
},
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
- FUZZ_LOG() << "about to readEmbeddedNativeHandle";
- size_t parent_buffer_handle = size & 0xf;
- size_t parent_offset = size >> 4;
- const native_handle_t* handle = nullptr;
- status_t status = p.readEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
- FUZZ_LOG() << "readEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
-
- // should be null since we don't create any IPC objects
- CHECK(handle == nullptr) << handle;
- },
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
- FUZZ_LOG() << "about to readNullableEmbeddedNativeHandle";
- size_t parent_buffer_handle = size & 0xf;
- size_t parent_offset = size >> 4;
- const native_handle_t* handle = nullptr;
- status_t status = p.readNullableEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
- FUZZ_LOG() << "readNullableEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
-
- // should be null since we don't create any IPC objects
- CHECK(handle == nullptr) << handle;
- },
[] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
FUZZ_LOG() << "about to readNativeHandleNoDup";
const native_handle_t* handle = nullptr;
@@ -180,14 +158,5 @@
CHECK(handle == nullptr) << handle;
CHECK(status != ::android::OK);
},
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
- FUZZ_LOG() << "about to readNullableNativeHandleNoDup";
- const native_handle_t* handle = nullptr;
- status_t status = p.readNullableNativeHandleNoDup(&handle);
- FUZZ_LOG() << "readNullableNativeHandleNoDup status: " << status << " handle: " << handle;
-
- // should be null since we don't create any IPC objects
- CHECK(handle == nullptr) << handle;
- },
};
// clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp
index a47b753..2a79e85 100644
--- a/libs/binder/tests/parcel_fuzzer/main.cpp
+++ b/libs/binder/tests/parcel_fuzzer/main.cpp
@@ -23,7 +23,8 @@
#include <iostream>
#include <android-base/logging.h>
-#include <binder/RpcSession.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_libbinder.h>
#include <fuzzbinder/random_parcel.h>
#include <fuzzer/FuzzedDataProvider.h>
@@ -33,7 +34,6 @@
#include <sys/time.h>
using android::fillRandomParcel;
-using android::RpcSession;
using android::sp;
void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) {
@@ -46,9 +46,22 @@
fillRandomParcel(p->parcel(), std::move(provider));
}
+template <typename P, typename B>
+void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider&& provider) {
+ uint32_t code = provider.ConsumeIntegral<uint32_t>();
+ uint32_t flag = provider.ConsumeIntegral<uint32_t>();
+
+ FUZZ_LOG() << "backend: " << backend;
+
+ P reply;
+ P data;
+ fillRandomParcel(&data, std::move(provider));
+ (void)binder->transact(code, data, &reply, flag);
+}
+
template <typename P>
-void doFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
- FuzzedDataProvider&& provider) {
+void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
+ FuzzedDataProvider&& provider) {
// Allow some majority of the bytes to be dedicated to telling us what to
// do. The fixed value added here represents that we want to test doing a
// lot of 'instructions' even on really short parcels.
@@ -59,18 +72,7 @@
provider.ConsumeIntegralInRange<size_t>(0, maxInstructions));
P p;
- if constexpr (std::is_same_v<P, android::Parcel>) {
- if (provider.ConsumeBool()) {
- auto session = sp<RpcSession>::make();
- CHECK(session->addNullDebuggingClient());
- p.markForRpc(session);
- fillRandomParcelData(&p, std::move(provider));
- } else {
- fillRandomParcel(&p, std::move(provider));
- }
- } else {
- fillRandomParcel(&p, std::move(provider));
- }
+ fillRandomParcel(&p, std::move(provider));
// since we are only using a byte to index
CHECK(reads.size() <= 255) << reads.size();
@@ -95,25 +97,18 @@
}
}
-size_t getHardMemoryLimit() {
- struct rlimit limit;
- CHECK(0 == getrlimit(RLIMIT_AS, &limit)) << errno;
- return limit.rlim_max;
+void* NothingClass_onCreate(void* args) {
+ return args;
}
-
-void setMemoryLimit(size_t cur, size_t max) {
- const struct rlimit kLimit = {
- .rlim_cur = cur,
- .rlim_max = max,
- };
- CHECK(0 == setrlimit(RLIMIT_AS, &kLimit)) << errno;
+void NothingClass_onDestroy(void* /*userData*/) {}
+binder_status_t NothingClass_onTransact(AIBinder*, transaction_code_t, const AParcel*, AParcel*) {
+ return STATUS_UNKNOWN_ERROR;
}
+static AIBinder_Class* kNothingClass =
+ AIBinder_Class_define("nothing", NothingClass_onCreate, NothingClass_onDestroy,
+ NothingClass_onTransact);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static constexpr size_t kMemLimit = 1 * 1024 * 1024;
- size_t hardLimit = getHardMemoryLimit();
- setMemoryLimit(std::min(kMemLimit, hardLimit), hardLimit);
-
if (size <= 1) return 0; // no use
// avoid timeouts, see b/142617274, b/142473153
@@ -121,24 +116,39 @@
FuzzedDataProvider provider = FuzzedDataProvider(data, size);
- const std::function<void(FuzzedDataProvider &&)> fuzzBackend[3] = {
+ const std::function<void(FuzzedDataProvider &&)> fuzzBackend[] = {
[](FuzzedDataProvider&& provider) {
- doFuzz<::android::hardware::Parcel>("hwbinder", HWBINDER_PARCEL_READ_FUNCTIONS,
- std::move(provider));
+ doTransactFuzz<
+ ::android::hardware::Parcel>("hwbinder",
+ sp<::android::hardware::BHwBinder>::make(),
+ std::move(provider));
},
[](FuzzedDataProvider&& provider) {
- doFuzz<::android::Parcel>("binder", BINDER_PARCEL_READ_FUNCTIONS,
- std::move(provider));
+ doTransactFuzz<::android::Parcel>("binder", sp<::android::BBinder>::make(),
+ std::move(provider));
},
[](FuzzedDataProvider&& provider) {
- doFuzz<NdkParcelAdapter>("binder_ndk", BINDER_NDK_PARCEL_READ_FUNCTIONS,
- std::move(provider));
+ // fuzz from the libbinder layer since it's a superset of the
+ // interface you get at the libbinder_ndk layer
+ auto ndkBinder = ndk::SpAIBinder(AIBinder_new(kNothingClass, nullptr));
+ auto binder = AIBinder_toPlatformBinder(ndkBinder.get());
+ doTransactFuzz<::android::Parcel>("binder_ndk", binder, std::move(provider));
+ },
+ [](FuzzedDataProvider&& provider) {
+ doReadFuzz<::android::hardware::Parcel>("hwbinder", HWBINDER_PARCEL_READ_FUNCTIONS,
+ std::move(provider));
+ },
+ [](FuzzedDataProvider&& provider) {
+ doReadFuzz<::android::Parcel>("binder", BINDER_PARCEL_READ_FUNCTIONS,
+ std::move(provider));
+ },
+ [](FuzzedDataProvider&& provider) {
+ doReadFuzz<NdkParcelAdapter>("binder_ndk", BINDER_NDK_PARCEL_READ_FUNCTIONS,
+ std::move(provider));
},
};
provider.PickValueInArray(fuzzBackend)(std::move(provider));
- setMemoryLimit(hardLimit, hardLimit);
-
return 0;
}
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index b045a22..92fdc72 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
#include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
#include <fuzzbinder/random_fd.h>
#include <utils/String16.h>
@@ -33,6 +34,14 @@
};
void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider) {
+ if (provider.ConsumeBool()) {
+ auto session = sp<RpcSession>::make();
+ CHECK(session->addNullDebuggingClient());
+ p->markForRpc(session);
+ fillRandomParcelData(p, std::move(provider));
+ return;
+ }
+
while (provider.remaining_bytes() > 0) {
auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
// write data
diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp
index 3603ebe..9fc496f 100644
--- a/libs/binder/tests/rpc_fuzzer/main.cpp
+++ b/libs/binder/tests/rpc_fuzzer/main.cpp
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <binder/Binder.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
+#include <fuzzer/FuzzedDataProvider.h>
#include <sys/resource.h>
#include <sys/un.h>
@@ -29,20 +29,6 @@
static const std::string kSock = std::string(getenv("TMPDIR") ?: "/tmp") +
"/binderRpcFuzzerSocket_" + std::to_string(getpid());
-size_t getHardMemoryLimit() {
- struct rlimit limit;
- CHECK(0 == getrlimit(RLIMIT_AS, &limit)) << errno;
- return limit.rlim_max;
-}
-
-void setMemoryLimit(size_t cur, size_t max) {
- const struct rlimit kLimit = {
- .rlim_cur = cur,
- .rlim_max = max,
- };
- CHECK(0 == setrlimit(RLIMIT_AS, &kLimit)) << errno;
-}
-
class SomeBinder : public BBinder {
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
(void)flags;
@@ -67,6 +53,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size > 50000) return 0;
+ FuzzedDataProvider provider(data, size);
unlink(kSock.c_str());
@@ -75,11 +62,7 @@
server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
CHECK(server->setupUnixDomainServer(kSock.c_str()));
- static constexpr size_t kMemLimit = 1llu * 1024 * 1024 * 1024;
- size_t hardLimit = getHardMemoryLimit();
- setMemoryLimit(std::min(kMemLimit, hardLimit), hardLimit);
-
- std::thread serverThread([=] { (void)server->acceptOne(); });
+ std::thread serverThread([=] { (void)server->join(); });
sockaddr_un addr{
.sun_family = AF_UNIX,
@@ -87,33 +70,45 @@
CHECK_LT(kSock.size(), sizeof(addr.sun_path));
memcpy(&addr.sun_path, kSock.c_str(), kSock.size());
- base::unique_fd clientFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
- CHECK_NE(clientFd.get(), -1);
- CHECK_EQ(0,
- TEMP_FAILURE_RETRY(
- connect(clientFd.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))))
- << strerror(errno);
+ std::vector<base::unique_fd> connections;
- serverThread.join();
+ bool hangupBeforeShutdown = provider.ConsumeBool();
- // TODO(b/182938024): fuzz multiple sessions, instead of just one
+ while (provider.remaining_bytes() > 0) {
+ if (connections.empty() || provider.ConsumeBool()) {
+ base::unique_fd fd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+ CHECK_NE(fd.get(), -1);
+ CHECK_EQ(0,
+ TEMP_FAILURE_RETRY(
+ connect(fd.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))))
+ << strerror(errno);
+ connections.push_back(std::move(fd));
+ } else {
+ size_t idx = provider.ConsumeIntegralInRange<size_t>(0, connections.size() - 1);
-#if 0
- // make fuzzer more productive locally by forcing it to create a new session
- int32_t id = -1;
- CHECK(base::WriteFully(clientFd, &id, sizeof(id)));
-#endif
-
- CHECK(base::WriteFully(clientFd, data, size));
-
- clientFd.reset();
-
- // TODO(b/185167543): better way to force a server to shutdown
- while (!server->listSessions().empty() && server->numUninitializedSessions()) {
- usleep(1);
+ if (provider.ConsumeBool()) {
+ std::vector<uint8_t> writeData = provider.ConsumeBytes<uint8_t>(
+ provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes()));
+ ssize_t size = TEMP_FAILURE_RETRY(send(connections.at(idx).get(), writeData.data(),
+ writeData.size(), MSG_NOSIGNAL));
+ CHECK(errno == EPIPE || size == writeData.size())
+ << size << " " << writeData.size() << " " << strerror(errno);
+ } else {
+ connections.erase(connections.begin() + idx); // hang up
+ }
+ }
}
- setMemoryLimit(hardLimit, hardLimit);
+ if (hangupBeforeShutdown) {
+ connections.clear();
+ while (!server->listSessions().empty() && server->numUninitializedSessions()) {
+ // wait for all threads to finish processing existing information
+ usleep(1);
+ }
+ }
+
+ while (!server->shutdown()) usleep(1);
+ serverThread.join();
return 0;
}
diff --git a/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
index 69f1b9d..8d2b714 100644
--- a/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
@@ -72,6 +72,10 @@
},
[](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
bbinder->getDebugPid();
+ },
+ [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
+ (void)bbinder->setRpcClientDebug(android::base::unique_fd(),
+ sp<BBinder>::make());
}};
} // namespace android
diff --git a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
index 626b758..4a0aeba 100644
--- a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
@@ -62,20 +62,22 @@
object = fdp->ConsumeIntegral<uint32_t>();
cleanup_cookie = fdp->ConsumeIntegral<uint32_t>();
IBinder::object_cleanup_func func = IBinder::object_cleanup_func();
- ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID)
- : nullptr,
- fdp->ConsumeBool() ? reinterpret_cast<void*>(&object) : nullptr,
- fdp->ConsumeBool() ? reinterpret_cast<void*>(&cleanup_cookie)
- : nullptr,
- func);
+ (void)ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID)
+ : nullptr,
+ fdp->ConsumeBool() ? reinterpret_cast<void*>(&object)
+ : nullptr,
+ fdp->ConsumeBool()
+ ? reinterpret_cast<void*>(&cleanup_cookie)
+ : nullptr,
+ func);
},
[](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
uint32_t id = fdp->ConsumeIntegral<uint32_t>();
- ibinder->findObject(reinterpret_cast<void*>(&id));
+ (void)ibinder->findObject(reinterpret_cast<void*>(&id));
},
[](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
uint32_t id = fdp->ConsumeIntegral<uint32_t>();
- ibinder->detachObject(reinterpret_cast<void*>(&id));
+ (void)ibinder->detachObject(reinterpret_cast<void*>(&id));
},
[](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
uint32_t code = fdp->ConsumeIntegral<uint32_t>();
diff --git a/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
index 8b4ed70..371dcbd 100644
--- a/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
@@ -31,37 +31,27 @@
static const std::vector<
std::function<void(FuzzedDataProvider*, android::sp<android::IBinder> const&)>>
gStabilityOperations = {
- // markCompilationUnit(IBinder* binder)
[](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
if (!marked) {
android::internal::Stability::markCompilationUnit(bbinder.get());
marked = true;
}
},
-
- // markVintf(IBinder* binder)
[](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
if (!marked) {
android::internal::Stability::markVintf(bbinder.get());
marked = true;
}
},
-
- // debugLogStability(const std::string& tag, const sp<IBinder>& binder)
- [](FuzzedDataProvider* fdp, android::sp<android::IBinder> const& bbinder) -> void {
- std::string tag = fdp->ConsumeRandomLengthString(STABILITY_MAX_TAG_LENGTH);
- android::internal::Stability::debugLogStability(tag, bbinder);
+ [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
+ (void)android::internal::Stability::debugToString(bbinder);
},
-
- // markVndk(IBinder* binder)
[](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
if (!marked) {
android::internal::Stability::markVndk(bbinder.get());
marked = true;
}
},
-
- // requiresVintfDeclaration(const sp<IBinder>& binder)
[](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
android::internal::Stability::requiresVintfDeclaration(bbinder);
}};
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index 97626be..3026921 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -14,10 +14,14 @@
address: true,
},
srcs: [
+ "cast_test.cpp",
+ "Flags_test.cpp",
"future_test.cpp",
+ "NamedEnum_test.cpp",
"small_map_test.cpp",
"small_vector_test.cpp",
"static_vector_test.cpp",
+ "string_test.cpp",
],
cflags: [
"-Wall",
@@ -25,4 +29,12 @@
"-Wextra",
"-Wpedantic",
],
+
+ header_libs: [
+ "libbase_headers",
+ ],
+
+ shared_libs: [
+ "libbase",
+ ],
}
diff --git a/libs/input/tests/Flags_test.cpp b/libs/ftl/Flags_test.cpp
similarity index 99%
rename from libs/input/tests/Flags_test.cpp
rename to libs/ftl/Flags_test.cpp
index 6de030f..8c00b52 100644
--- a/libs/input/tests/Flags_test.cpp
+++ b/libs/ftl/Flags_test.cpp
@@ -15,7 +15,7 @@
*/
#include <gtest/gtest.h>
-#include <input/Flags.h>
+#include <ftl/Flags.h>
#include <type_traits>
diff --git a/libs/input/tests/NamedEnum_test.cpp b/libs/ftl/NamedEnum_test.cpp
similarity index 98%
rename from libs/input/tests/NamedEnum_test.cpp
rename to libs/ftl/NamedEnum_test.cpp
index 74a0044..dff2b8a 100644
--- a/libs/input/tests/NamedEnum_test.cpp
+++ b/libs/ftl/NamedEnum_test.cpp
@@ -15,7 +15,7 @@
*/
#include <gtest/gtest.h>
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
namespace android {
diff --git a/libs/ftl/cast_test.cpp b/libs/ftl/cast_test.cpp
new file mode 100644
index 0000000..2abcb8f
--- /dev/null
+++ b/libs/ftl/cast_test.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 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 <ftl/cast.h>
+#include <gtest/gtest.h>
+
+#include <cfloat>
+#include <cmath>
+#include <limits>
+
+namespace android::test {
+
+using ftl::cast_safety;
+using ftl::CastSafety;
+
+template <typename T>
+constexpr T min = std::numeric_limits<T>::lowest();
+
+template <typename T>
+constexpr T max = std::numeric_limits<T>::max();
+
+template <typename T>
+constexpr T inf = std::numeric_limits<T>::infinity();
+
+template <typename T>
+constexpr T NaN = std::numeric_limits<T>::quiet_NaN();
+
+// Keep in sync with example usage in header file.
+
+static_assert(cast_safety<uint8_t>(-1) == CastSafety::kUnderflow);
+static_assert(cast_safety<int8_t>(128u) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(-.1f) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(static_cast<float>(INT32_MAX)) == CastSafety::kOverflow);
+
+static_assert(cast_safety<float>(-DBL_MAX) == CastSafety::kUnderflow);
+
+// Unsigned to unsigned.
+
+static_assert(cast_safety<uint8_t>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<uint8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<uint8_t>(static_cast<uint32_t>(max<uint8_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint32_t>(max<uint64_t>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint8_t>(static_cast<uint32_t>(max<uint8_t>) + 1) ==
+ CastSafety::kOverflow);
+
+// Unsigned to signed.
+
+static_assert(cast_safety<int16_t>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<int16_t>(max<uint8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<int16_t>(max<uint16_t>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>) - 1) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>) + 1) ==
+ CastSafety::kOverflow);
+
+// Signed to unsigned.
+
+static_assert(cast_safety<uint16_t>(0) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<int8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<int16_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint32_t>(-1) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(max<int64_t>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>) - 1) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>) + 1) ==
+ CastSafety::kOverflow);
+
+// Signed to signed.
+
+static_assert(cast_safety<int8_t>(-129) == CastSafety::kUnderflow);
+static_assert(cast_safety<int8_t>(-128) == CastSafety::kSafe);
+static_assert(cast_safety<int8_t>(127) == CastSafety::kSafe);
+static_assert(cast_safety<int8_t>(128) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int32_t>(static_cast<int64_t>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<int64_t>(max<int32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<int16_t>(min<int32_t>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(max<int64_t>) == CastSafety::kOverflow);
+
+// Float to float.
+
+static_assert(cast_safety<double>(max<float>) == CastSafety::kSafe);
+static_assert(cast_safety<double>(min<float>) == CastSafety::kSafe);
+
+static_assert(cast_safety<float>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<float>(max<double>) == CastSafety::kOverflow);
+
+TEST(CastSafety, FloatToFloat) {
+ EXPECT_EQ(cast_safety<float>(std::nexttoward(static_cast<double>(min<float>), min<double>)),
+ CastSafety::kUnderflow);
+ EXPECT_EQ(cast_safety<float>(std::nexttoward(static_cast<double>(max<float>), max<double>)),
+ CastSafety::kOverflow);
+}
+
+// Unsigned to float.
+
+static_assert(cast_safety<float>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<float>(max<uint64_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<double>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<double>(max<uint64_t>) == CastSafety::kSafe);
+
+// Signed to float.
+
+static_assert(cast_safety<float>(min<int64_t>) == CastSafety::kSafe);
+static_assert(cast_safety<float>(max<int64_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<double>(min<int64_t>) == CastSafety::kSafe);
+static_assert(cast_safety<double>(max<int64_t>) == CastSafety::kSafe);
+
+// Float to unsigned.
+
+static_assert(cast_safety<uint32_t>(0.f) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(min<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(max<float>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint32_t>(-.1f) == CastSafety::kUnderflow);
+
+static_assert(cast_safety<uint16_t>(-inf<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(inf<float>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(NaN<float>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(static_cast<float>(max<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<float>(max<uint32_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<uint32_t>(static_cast<double>(max<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<double>(max<uint32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint64_t>(0.0) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint64_t>(max<double>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(-.1) == CastSafety::kUnderflow);
+
+static_assert(cast_safety<uint64_t>(static_cast<float>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(static_cast<float>(max<uint64_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(static_cast<double>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(static_cast<double>(max<uint64_t>)) == CastSafety::kOverflow);
+
+// Float to signed.
+
+static_assert(cast_safety<int32_t>(0.f) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(min<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(max<float>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int16_t>(-inf<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(inf<double>) == CastSafety::kOverflow);
+static_assert(cast_safety<int64_t>(NaN<double>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int32_t>(static_cast<float>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<float>(max<int32_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<int32_t>(static_cast<double>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<double>(max<int32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<int64_t>(0.0) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int64_t>(max<double>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int64_t>(static_cast<float>(min<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<float>(max<int64_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<int64_t>(static_cast<double>(min<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<double>(max<int64_t>)) == CastSafety::kOverflow);
+
+TEST(CastSafety, FloatToSigned) {
+ constexpr int32_t kMax = ftl::details::safe_limits<int32_t, float>::max();
+ static_assert(kMax == 2'147'483'520);
+ EXPECT_EQ(kMax, static_cast<int32_t>(std::nexttowardf(max<int32_t>, 0)));
+
+ EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(min<int32_t>, 0)), CastSafety::kSafe);
+ EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(max<int32_t>, 0)), CastSafety::kSafe);
+ EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(min<int64_t>, 0)), CastSafety::kSafe);
+ EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(max<int64_t>, 0)), CastSafety::kSafe);
+
+ EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(min<int32_t>, min<float>)),
+ CastSafety::kUnderflow);
+ EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(max<int32_t>, max<float>)),
+ CastSafety::kOverflow);
+ EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(min<int64_t>, min<double>)),
+ CastSafety::kUnderflow);
+ EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(max<int64_t>, max<double>)),
+ CastSafety::kOverflow);
+}
+
+} // namespace android::test
diff --git a/libs/ftl/small_map_test.cpp b/libs/ftl/small_map_test.cpp
index 323b9f9..2e81022 100644
--- a/libs/ftl/small_map_test.cpp
+++ b/libs/ftl/small_map_test.cpp
@@ -18,6 +18,9 @@
#include <gtest/gtest.h>
#include <cctype>
+#include <string>
+
+using namespace std::string_literals;
namespace android::test {
@@ -35,16 +38,19 @@
EXPECT_TRUE(map.contains(123));
- EXPECT_EQ(map.find(42, [](const std::string& s) { return s.size(); }), 3u);
+ EXPECT_EQ(map.get(42, [](const std::string& s) { return s.size(); }), 3u);
- const auto opt = map.find(-1);
+ const auto opt = map.get(-1);
ASSERT_TRUE(opt);
std::string& ref = *opt;
EXPECT_TRUE(ref.empty());
ref = "xyz";
- EXPECT_EQ(map, SmallMap(ftl::init::map(-1, "xyz")(42, "???")(123, "abc")));
+ map.emplace_or_replace(0, "vanilla", 2u, 3u);
+ EXPECT_TRUE(map.dynamic());
+
+ EXPECT_EQ(map, SmallMap(ftl::init::map(-1, "xyz")(0, "nil")(42, "???")(123, "abc")));
}
TEST(SmallMap, Construct) {
@@ -90,42 +96,253 @@
}
}
+TEST(SmallMap, UniqueKeys) {
+ {
+ // Duplicate mappings are discarded.
+ const SmallMap map = ftl::init::map<int, float>(1)(2)(3)(2)(3)(1)(3)(2)(1);
+
+ EXPECT_EQ(map.size(), 3u);
+ EXPECT_EQ(map.max_size(), 9u);
+
+ using Map = decltype(map);
+ EXPECT_EQ(map, Map(ftl::init::map(1, 0.f)(2, 0.f)(3, 0.f)));
+ }
+ {
+ // Duplicate mappings may be reordered.
+ const SmallMap map = ftl::init::map('a', 'A')(
+ 'b', 'B')('b')('b')('c', 'C')('a')('d')('c')('e', 'E')('d', 'D')('a')('f', 'F');
+
+ EXPECT_EQ(map.size(), 6u);
+ EXPECT_EQ(map.max_size(), 12u);
+
+ using Map = decltype(map);
+ EXPECT_EQ(map, Map(ftl::init::map('a', 'A')('b', 'B')('c', 'C')('d', 'D')('e', 'E')('f', 'F')));
+ }
+}
+
TEST(SmallMap, Find) {
{
// Constant reference.
- const ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
+ const SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
- const auto opt = map.find('b');
+ const auto opt = map.get('b');
EXPECT_EQ(opt, 'B');
const char d = 'D';
- const auto ref = map.find('d').value_or(std::cref(d));
+ const auto ref = map.get('d').value_or(std::cref(d));
EXPECT_EQ(ref.get(), 'D');
}
{
// Mutable reference.
- ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
+ SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
- const auto opt = map.find('c');
+ const auto opt = map.get('c');
EXPECT_EQ(opt, 'C');
char d = 'd';
- const auto ref = map.find('d').value_or(std::ref(d));
+ const auto ref = map.get('d').value_or(std::ref(d));
ref.get() = 'D';
EXPECT_EQ(d, 'D');
}
{
// Constant unary operation.
- const ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
- EXPECT_EQ(map.find('c', [](char c) { return std::toupper(c); }), 'Z');
+ const SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
+ EXPECT_EQ(map.get('c', [](char c) { return std::toupper(c); }), 'Z');
}
{
// Mutable unary operation.
- ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
- EXPECT_TRUE(map.find('c', [](char& c) { c = std::toupper(c); }));
+ SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
+ EXPECT_TRUE(map.get('c', [](char& c) { c = std::toupper(c); }));
EXPECT_EQ(map, SmallMap(ftl::init::map('c', 'Z')('b', 'y')('a', 'x')));
}
}
+TEST(SmallMap, TryEmplace) {
+ SmallMap<int, std::string, 3> map;
+ using Pair = decltype(map)::value_type;
+
+ {
+ const auto [it, ok] = map.try_emplace(123, "abc");
+ ASSERT_TRUE(ok);
+ EXPECT_EQ(*it, Pair(123, "abc"s));
+ }
+ {
+ const auto [it, ok] = map.try_emplace(42, 3u, '?');
+ ASSERT_TRUE(ok);
+ EXPECT_EQ(*it, Pair(42, "???"s));
+ }
+ {
+ const auto [it, ok] = map.try_emplace(-1);
+ ASSERT_TRUE(ok);
+ EXPECT_EQ(*it, Pair(-1, std::string()));
+ EXPECT_FALSE(map.dynamic());
+ }
+ {
+ // Insertion fails if mapping exists.
+ const auto [it, ok] = map.try_emplace(42, "!!!");
+ EXPECT_FALSE(ok);
+ EXPECT_EQ(*it, Pair(42, "???"));
+ EXPECT_FALSE(map.dynamic());
+ }
+ {
+ // Insertion at capacity promotes the map.
+ const auto [it, ok] = map.try_emplace(999, "xyz");
+ ASSERT_TRUE(ok);
+ EXPECT_EQ(*it, Pair(999, "xyz"));
+ EXPECT_TRUE(map.dynamic());
+ }
+
+ EXPECT_EQ(map, SmallMap(ftl::init::map(-1, ""s)(42, "???"s)(123, "abc"s)(999, "xyz"s)));
+}
+
+namespace {
+
+// The mapped type does not require a copy/move assignment operator.
+struct String {
+ template <typename... Args>
+ String(Args... args) : str(args...) {}
+ const std::string str;
+
+ bool operator==(const String& other) const { return other.str == str; }
+};
+
+} // namespace
+
+TEST(SmallMap, TryReplace) {
+ SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B");
+ using Pair = decltype(map)::value_type;
+
+ {
+ // Replacing fails unless mapping exists.
+ const auto it = map.try_replace(3, "c");
+ EXPECT_EQ(it, map.end());
+ }
+ {
+ // Replacement arguments can refer to the replaced mapping.
+ const auto ref = map.get(2, [](const auto& s) { return s.str[0]; });
+ ASSERT_TRUE(ref);
+
+ // Construct std::string from one character.
+ const auto it = map.try_replace(2, 1u, static_cast<char>(std::tolower(*ref)));
+ ASSERT_NE(it, map.end());
+ EXPECT_EQ(*it, Pair(2, "b"));
+ }
+
+ EXPECT_FALSE(map.dynamic());
+ EXPECT_TRUE(map.try_emplace(3, "abc").second);
+ EXPECT_TRUE(map.try_emplace(4, "d").second);
+ EXPECT_TRUE(map.dynamic());
+
+ {
+ // Replacing fails unless mapping exists.
+ const auto it = map.try_replace(5, "e");
+ EXPECT_EQ(it, map.end());
+ }
+ {
+ // Replacement arguments can refer to the replaced mapping.
+ const auto ref = map.get(3);
+ ASSERT_TRUE(ref);
+
+ // Construct std::string from substring.
+ const auto it = map.try_replace(3, ref->get().str, 2u, 1u);
+ ASSERT_NE(it, map.end());
+ EXPECT_EQ(*it, Pair(3, "c"));
+ }
+
+ EXPECT_EQ(map, SmallMap(ftl::init::map(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s)));
+}
+
+TEST(SmallMap, EmplaceOrReplace) {
+ SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B");
+ using Pair = decltype(map)::value_type;
+
+ {
+ // New mapping is emplaced.
+ const auto [it, emplace] = map.emplace_or_replace(3, "c");
+ EXPECT_TRUE(emplace);
+ EXPECT_EQ(*it, Pair(3, "c"));
+ }
+ {
+ // Replacement arguments can refer to the replaced mapping.
+ const auto ref = map.get(2, [](const auto& s) { return s.str[0]; });
+ ASSERT_TRUE(ref);
+
+ // Construct std::string from one character.
+ const auto [it, emplace] = map.emplace_or_replace(2, 1u, static_cast<char>(std::tolower(*ref)));
+ EXPECT_FALSE(emplace);
+ EXPECT_EQ(*it, Pair(2, "b"));
+ }
+
+ EXPECT_FALSE(map.dynamic());
+ EXPECT_FALSE(map.emplace_or_replace(3, "abc").second); // Replace.
+ EXPECT_TRUE(map.emplace_or_replace(4, "d").second); // Emplace.
+ EXPECT_TRUE(map.dynamic());
+
+ {
+ // New mapping is emplaced.
+ const auto [it, emplace] = map.emplace_or_replace(5, "e");
+ EXPECT_TRUE(emplace);
+ EXPECT_EQ(*it, Pair(5, "e"));
+ }
+ {
+ // Replacement arguments can refer to the replaced mapping.
+ const auto ref = map.get(3);
+ ASSERT_TRUE(ref);
+
+ // Construct std::string from substring.
+ const auto [it, emplace] = map.emplace_or_replace(3, ref->get().str, 2u, 1u);
+ EXPECT_FALSE(emplace);
+ EXPECT_EQ(*it, Pair(3, "c"));
+ }
+
+ EXPECT_EQ(map, SmallMap(ftl::init::map(5, "e"s)(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s)));
+}
+
+TEST(SmallMap, Erase) {
+ {
+ SmallMap map = ftl::init::map(1, '1')(2, '2')(3, '3')(4, '4');
+ EXPECT_FALSE(map.dynamic());
+
+ EXPECT_FALSE(map.erase(0)); // Key not found.
+
+ EXPECT_TRUE(map.erase(2));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(1, '1')(3, '3')(4, '4')));
+
+ EXPECT_TRUE(map.erase(1));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')(4, '4')));
+
+ EXPECT_TRUE(map.erase(4));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')));
+
+ EXPECT_TRUE(map.erase(3));
+ EXPECT_FALSE(map.erase(3)); // Key not found.
+
+ EXPECT_TRUE(map.empty());
+ EXPECT_FALSE(map.dynamic());
+ }
+ {
+ SmallMap map = ftl::init::map(1, '1')(2, '2')(3, '3');
+ map.try_emplace(4, '4');
+ EXPECT_TRUE(map.dynamic());
+
+ EXPECT_FALSE(map.erase(0)); // Key not found.
+
+ EXPECT_TRUE(map.erase(2));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(1, '1')(3, '3')(4, '4')));
+
+ EXPECT_TRUE(map.erase(1));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')(4, '4')));
+
+ EXPECT_TRUE(map.erase(4));
+ EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')));
+
+ EXPECT_TRUE(map.erase(3));
+ EXPECT_FALSE(map.erase(3)); // Key not found.
+
+ EXPECT_TRUE(map.empty());
+ EXPECT_TRUE(map.dynamic());
+ }
+}
+
} // namespace android::test
diff --git a/libs/ftl/string_test.cpp b/libs/ftl/string_test.cpp
new file mode 100644
index 0000000..f3d85c8
--- /dev/null
+++ b/libs/ftl/string_test.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright 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 <ftl/string.h>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <sstream>
+#include <type_traits>
+
+namespace android::test {
+
+// Keep in sync with example usage in header file.
+TEST(String, ToChars) {
+ ftl::to_chars_buffer_t<> buffer;
+
+ EXPECT_EQ(ftl::to_chars(buffer, 123u), "123");
+ EXPECT_EQ(ftl::to_chars(buffer, -42, ftl::Radix::kBin), "-0b101010");
+ EXPECT_EQ(ftl::to_chars(buffer, 0xcafe, ftl::Radix::kHex), "0xcafe");
+ EXPECT_EQ(ftl::to_chars(buffer, '*', ftl::Radix::kHex), "0x2a");
+}
+
+namespace {
+
+template <typename F, typename T>
+void ToCharsTest() {
+ constexpr auto kRadix = F::kRadix;
+
+ using Limits = std::numeric_limits<T>;
+ constexpr auto kMin = Limits::min();
+ constexpr auto kMax = Limits::max();
+ constexpr auto kNeg = static_cast<T>(-42);
+ constexpr auto kPos = static_cast<T>(123);
+
+ ftl::to_chars_buffer_t<T> buffer;
+
+ EXPECT_EQ(ftl::to_chars(buffer, kMin, kRadix), F{}(kMin));
+ EXPECT_EQ(ftl::to_chars(buffer, kMax, kRadix), F{}(kMax));
+ EXPECT_EQ(ftl::to_chars(buffer, kNeg, kRadix), F{}(kNeg));
+ EXPECT_EQ(ftl::to_chars(buffer, kPos, kRadix), F{}(kPos));
+}
+
+template <typename...>
+struct Types {};
+
+template <typename F, typename Types>
+struct ToCharsTests;
+
+template <typename F, typename T, typename... Ts>
+struct ToCharsTests<F, Types<T, Ts...>> {
+ static void test() {
+ ToCharsTest<F, T>();
+ ToCharsTests<F, Types<Ts...>>::test();
+ }
+};
+
+template <typename F>
+struct ToCharsTests<F, Types<>> {
+ static void test() {}
+};
+
+template <typename T, typename U = std::make_unsigned_t<T>>
+U to_unsigned(std::ostream& stream, T v) {
+ if (std::is_same_v<T, U>) return v;
+
+ if (v < 0) {
+ stream << '-';
+ return std::numeric_limits<U>::max() - static_cast<U>(v) + 1;
+ } else {
+ return static_cast<U>(v);
+ }
+}
+
+struct Bin {
+ static constexpr auto kRadix = ftl::Radix::kBin;
+
+ template <typename T>
+ std::string operator()(T v) const {
+ std::ostringstream stream;
+ auto u = to_unsigned(stream, v);
+ stream << "0b";
+
+ if (u == 0) {
+ stream << 0;
+ } else {
+ std::ostringstream digits;
+ do {
+ digits << (u & 1);
+ } while (u >>= 1);
+
+ const auto str = digits.str();
+ std::copy(str.rbegin(), str.rend(), std::ostream_iterator<char>(stream));
+ }
+
+ return stream.str();
+ }
+};
+
+struct Dec {
+ static constexpr auto kRadix = ftl::Radix::kDec;
+
+ template <typename T>
+ std::string operator()(T v) const {
+ return std::to_string(v);
+ }
+};
+
+struct Hex {
+ static constexpr auto kRadix = ftl::Radix::kHex;
+
+ template <typename T>
+ std::string operator()(T v) const {
+ std::ostringstream stream;
+ const auto u = to_unsigned(stream, v);
+ stream << "0x" << std::hex << std::nouppercase;
+ stream << (sizeof(T) == 1 ? static_cast<unsigned>(u) : u);
+ return stream.str();
+ }
+};
+
+using IntegerTypes =
+ Types<char, unsigned char, signed char, std::uint8_t, std::uint16_t, std::uint32_t,
+ std::uint64_t, std::int8_t, std::int16_t, std::int32_t, std::int64_t>;
+
+} // namespace
+
+TEST(String, ToCharsBin) {
+ ToCharsTests<Bin, IntegerTypes>::test();
+
+ {
+ const std::uint8_t x = 0b1111'1111;
+ ftl::to_chars_buffer_t<decltype(x)> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kBin), "0b11111111");
+ }
+ {
+ const std::int16_t x = -0b1000'0000'0000'0000;
+ ftl::to_chars_buffer_t<decltype(x)> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kBin), "-0b1000000000000000");
+ }
+}
+
+TEST(String, ToCharsDec) {
+ ToCharsTests<Dec, IntegerTypes>::test();
+
+ {
+ const std::uint32_t x = UINT32_MAX;
+ ftl::to_chars_buffer_t<decltype(x)> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, x), "4294967295");
+ }
+ {
+ const std::int32_t x = INT32_MIN;
+ ftl::to_chars_buffer_t<decltype(x)> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, x), "-2147483648");
+ }
+}
+
+TEST(String, ToCharsHex) {
+ ToCharsTests<Hex, IntegerTypes>::test();
+
+ {
+ const std::uint16_t x = 0xfade;
+ ftl::to_chars_buffer_t<decltype(x)> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kHex), "0xfade");
+ }
+ {
+ ftl::to_chars_buffer_t<> buffer;
+ EXPECT_EQ(ftl::to_chars(buffer, INT64_MIN, ftl::Radix::kHex), "-0x8000000000000000");
+ }
+}
+
+} // namespace android::test
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index d54de49..7f0cac5 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -343,80 +343,6 @@
return nullptr;
}
-bool GraphicsEnv::checkAngleRules(void* so) {
- auto manufacturer = base::GetProperty("ro.product.manufacturer", "UNSET");
- auto model = base::GetProperty("ro.product.model", "UNSET");
-
- auto ANGLEGetFeatureSupportUtilAPIVersion =
- (fpANGLEGetFeatureSupportUtilAPIVersion)dlsym(so,
- "ANGLEGetFeatureSupportUtilAPIVersion");
-
- if (!ANGLEGetFeatureSupportUtilAPIVersion) {
- ALOGW("Cannot find ANGLEGetFeatureSupportUtilAPIVersion function");
- return false;
- }
-
- // Negotiate the interface version by requesting most recent known to the platform
- unsigned int versionToUse = CURRENT_ANGLE_API_VERSION;
- if (!(ANGLEGetFeatureSupportUtilAPIVersion)(&versionToUse)) {
- ALOGW("Cannot use ANGLE feature-support library, it is older than supported by EGL, "
- "requested version %u",
- versionToUse);
- return false;
- }
-
- // Add and remove versions below as needed
- bool useAngle = false;
- switch (versionToUse) {
- case 2: {
- ALOGV("Using version %d of ANGLE feature-support library", versionToUse);
- void* rulesHandle = nullptr;
- int rulesVersion = 0;
- void* systemInfoHandle = nullptr;
-
- // Get the symbols for the feature-support-utility library:
-#define GET_SYMBOL(symbol) \
- fp##symbol symbol = (fp##symbol)dlsym(so, #symbol); \
- if (!symbol) { \
- ALOGW("Cannot find " #symbol " in ANGLE feature-support library"); \
- break; \
- }
- GET_SYMBOL(ANGLEAndroidParseRulesString);
- GET_SYMBOL(ANGLEGetSystemInfo);
- GET_SYMBOL(ANGLEAddDeviceInfoToSystemInfo);
- GET_SYMBOL(ANGLEShouldBeUsedForApplication);
- GET_SYMBOL(ANGLEFreeRulesHandle);
- GET_SYMBOL(ANGLEFreeSystemInfoHandle);
-
- // Parse the rules, obtain the SystemInfo, and evaluate the
- // application against the rules:
- if (!(ANGLEAndroidParseRulesString)(mRulesBuffer.data(), &rulesHandle, &rulesVersion)) {
- ALOGW("ANGLE feature-support library cannot parse rules file");
- break;
- }
- if (!(ANGLEGetSystemInfo)(&systemInfoHandle)) {
- ALOGW("ANGLE feature-support library cannot obtain SystemInfo");
- break;
- }
- if (!(ANGLEAddDeviceInfoToSystemInfo)(manufacturer.c_str(), model.c_str(),
- systemInfoHandle)) {
- ALOGW("ANGLE feature-support library cannot add device info to SystemInfo");
- break;
- }
- useAngle = (ANGLEShouldBeUsedForApplication)(rulesHandle, rulesVersion,
- systemInfoHandle, mAngleAppName.c_str());
- (ANGLEFreeRulesHandle)(rulesHandle);
- (ANGLEFreeSystemInfoHandle)(systemInfoHandle);
- } break;
-
- default:
- ALOGW("Version %u of ANGLE feature-support library is NOT supported.", versionToUse);
- }
-
- ALOGV("Close temporarily-loaded ANGLE opt-in/out logic");
- return useAngle;
-}
-
bool GraphicsEnv::shouldUseAngle(std::string appName) {
if (appName != mAngleAppName) {
// Make sure we are checking the app we were init'ed for
@@ -444,31 +370,20 @@
const char* ANGLE_PREFER_ANGLE = "angle";
const char* ANGLE_PREFER_NATIVE = "native";
+ mUseAngle = NO;
if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
ALOGV("User set \"Developer Options\" to force the use of ANGLE");
mUseAngle = YES;
} else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
ALOGV("User set \"Developer Options\" to force the use of Native");
- mUseAngle = NO;
} else {
- // The "Developer Options" value wasn't set to force the use of ANGLE. Need to temporarily
- // load ANGLE and call the updatable opt-in/out logic:
- void* featureSo = loadLibrary("feature_support");
- if (featureSo) {
- ALOGV("loaded ANGLE's opt-in/out logic from namespace");
- mUseAngle = checkAngleRules(featureSo) ? YES : NO;
- dlclose(featureSo);
- featureSo = nullptr;
- } else {
- ALOGV("Could not load the ANGLE opt-in/out logic, cannot use ANGLE.");
- }
+ ALOGV("User set invalid \"Developer Options\": '%s'", mAngleDeveloperOptIn.c_str());
}
}
void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
const std::string developerOptIn,
- const std::vector<std::string> eglFeatures, const int rulesFd,
- const long rulesOffset, const long rulesLength) {
+ const std::vector<std::string> eglFeatures) {
if (mUseAngle != UNKNOWN) {
// We've already figured out an answer for this app, so just return.
ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", appName.c_str(),
@@ -485,22 +400,6 @@
ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
mAngleDeveloperOptIn = developerOptIn;
- lseek(rulesFd, rulesOffset, SEEK_SET);
- mRulesBuffer = std::vector<char>(rulesLength + 1);
- ssize_t numBytesRead = read(rulesFd, mRulesBuffer.data(), rulesLength);
- if (numBytesRead < 0) {
- ALOGE("Cannot read rules file: numBytesRead = %zd", numBytesRead);
- numBytesRead = 0;
- } else if (numBytesRead == 0) {
- ALOGW("Empty rules file");
- }
- if (numBytesRead != rulesLength) {
- ALOGW("Did not read all of the necessary bytes from the rules file."
- "expected: %ld, got: %zd",
- rulesLength, numBytesRead);
- }
- mRulesBuffer[numBytesRead] = '\0';
-
// Update the current status of whether we should use ANGLE or not
updateUseAngle();
}
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 900fc49..56d1139 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -97,8 +97,7 @@
// in the search path must have a '!' after the zip filename, e.g.
// /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
- const std::vector<std::string> eglFeatures, const int rulesFd,
- const long rulesOffset, const long rulesLength);
+ const std::vector<std::string> eglFeatures);
// Get the ANGLE driver namespace.
android_namespace_t* getAngleNamespace();
// Get the app name for ANGLE debug message.
@@ -129,8 +128,6 @@
// Load requested ANGLE library.
void* loadLibrary(std::string name);
- // Check ANGLE support with the rules.
- bool checkAngleRules(void* so);
// Update whether ANGLE should be used.
void updateUseAngle();
// Link updatable driver namespace with llndk and vndk-sp libs.
@@ -159,8 +156,6 @@
std::string mAngleDeveloperOptIn;
// ANGLE EGL features;
std::vector<std::string> mAngleEglFeatures;
- // ANGLE rules.
- std::vector<char> mRulesBuffer;
// Use ANGLE flag.
UseAngle mUseAngle = UNKNOWN;
// Vulkan debug layers libs.
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 64203f7..b0dc27f 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -51,6 +51,57 @@
],
}
+// AIDL files that should be exposed to java
+filegroup {
+ name: "guiconstants_aidl",
+ srcs: [
+ "android/**/TouchOcclusionMode.aidl",
+ ],
+}
+
+cc_library_static {
+ name: "libgui_window_info_static",
+ vendor_available: true,
+ host_supported: true,
+ srcs: [
+ ":guiconstants_aidl",
+ "android/gui/FocusRequest.aidl",
+ "android/gui/InputApplicationInfo.aidl",
+ "android/gui/WindowInfo.aidl",
+ "WindowInfo.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+
+ export_shared_lib_headers: [
+ "libbinder",
+ ],
+
+ static_libs: [
+ "libui-types",
+ ],
+
+ aidl: {
+ export_aidl_headers: true
+ },
+
+ include_dirs: [
+ "frameworks/native/include",
+ ],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
+
filegroup {
name: "libgui_aidl",
srcs: ["aidl/**/*.aidl"],
@@ -77,12 +128,15 @@
"libbinder",
],
+ static_libs: [
+ "libui-types",
+ ],
+
aidl: {
export_aidl_headers: true
}
}
-
cc_library_shared {
name: "libgui",
vendor_available: true,
@@ -96,9 +150,11 @@
static_libs: [
"libgui_aidl_static",
+ "libgui_window_info_static",
],
export_static_lib_headers: [
"libgui_aidl_static",
+ "libgui_window_info_static",
],
srcs: [
@@ -150,13 +206,11 @@
"libbinder",
"libbufferhub",
"libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
- "libinput",
"libpdx_default_transport",
],
export_shared_lib_headers: [
"libbinder",
- "libinput",
],
export_header_lib_headers: [
@@ -168,7 +222,6 @@
vendor: {
cflags: [
"-DNO_BUFFERHUB",
- "-DNO_INPUT",
],
exclude_srcs: [
"BufferHubConsumer.cpp",
@@ -178,7 +231,6 @@
"android.frameworks.bufferhub@1.0",
"libbufferhub",
"libbufferhubqueue",
- "libinput",
"libpdx_default_transport",
],
},
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 7d57d8b..d9024fa 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -38,7 +38,7 @@
using namespace std::chrono_literals;
namespace {
-inline const char* toString(bool b) {
+inline const char* boolToString(bool b) {
return b ? "true" : "false";
}
} // namespace
@@ -521,7 +521,7 @@
BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
" applyTransaction=%s mTimestamp=%" PRId64 "%s mPendingTransactions.size=%d"
" graphicBufferId=%" PRIu64 "%s transform=%d",
- mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction),
+ mSize.width, mSize.height, bufferItem.mFrameNumber, boolToString(applyTransaction),
bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "",
static_cast<uint32_t>(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(),
bufferItem.mAutoRefresh ? " mAutoRefresh" : "", bufferItem.mTransform);
@@ -551,7 +551,7 @@
mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s", item.mFrameNumber,
- toString(nextTransactionSet));
+ boolToString(nextTransactionSet));
processNextBufferLocked(nextTransactionSet /* useNextTransaction */);
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0d7795e..bab9ebf 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -123,11 +123,11 @@
return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
}
- status_t captureDisplay(uint64_t displayOrLayerStack,
+ status_t captureDisplay(DisplayId displayId,
const sp<IScreenCaptureListener>& captureListener) override {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeUint64, displayOrLayerStack);
+ SAFE_PARCEL(data.writeUint64, displayId.value);
SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));
return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
@@ -281,9 +281,14 @@
NO_ERROR) {
std::vector<uint64_t> rawIds;
if (reply.readUint64Vector(&rawIds) == NO_ERROR) {
- std::vector<PhysicalDisplayId> displayIds(rawIds.size());
- std::transform(rawIds.begin(), rawIds.end(), displayIds.begin(),
- [](uint64_t rawId) { return PhysicalDisplayId(rawId); });
+ std::vector<PhysicalDisplayId> displayIds;
+ displayIds.reserve(rawIds.size());
+
+ for (const uint64_t rawId : rawIds) {
+ if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(rawId)) {
+ displayIds.push_back(*id);
+ }
+ }
return displayIds;
}
}
@@ -1327,12 +1332,15 @@
}
case CAPTURE_DISPLAY_BY_ID: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- uint64_t displayOrLayerStack = 0;
+ uint64_t value;
+ SAFE_PARCEL(data.readUint64, &value);
+ const auto id = DisplayId::fromValue(value);
+ if (!id) return BAD_VALUE;
+
sp<IScreenCaptureListener> captureListener;
- SAFE_PARCEL(data.readUint64, &displayOrLayerStack);
SAFE_PARCEL(data.readStrongBinder, &captureListener);
- return captureDisplay(displayOrLayerStack, captureListener);
+ return captureDisplay(*id, captureListener);
}
case CAPTURE_LAYERS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
@@ -1399,9 +1407,9 @@
}
case GET_PHYSICAL_DISPLAY_TOKEN: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- PhysicalDisplayId displayId(data.readUint64());
- sp<IBinder> display = getPhysicalDisplayToken(displayId);
- reply->writeStrongBinder(display);
+ const auto id = DisplayId::fromValue<PhysicalDisplayId>(data.readUint64());
+ if (!id) return BAD_VALUE;
+ reply->writeStrongBinder(getPhysicalDisplayToken(*id));
return NO_ERROR;
}
case GET_DISPLAY_STATE: {
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 076c90d..23895c0 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -31,6 +31,9 @@
namespace android {
+using gui::FocusRequest;
+using gui::WindowInfoHandle;
+
layer_state_t::layer_state_t()
: what(0),
x(0),
@@ -95,9 +98,7 @@
SAFE_PARCEL(output.writeFloat, color.r);
SAFE_PARCEL(output.writeFloat, color.g);
SAFE_PARCEL(output.writeFloat, color.b);
-#ifndef NO_INPUT
- SAFE_PARCEL(inputHandle->writeToParcel, &output);
-#endif
+ SAFE_PARCEL(windowInfoHandle->writeToParcel, &output);
SAFE_PARCEL(output.write, transparentRegion);
SAFE_PARCEL(output.writeUint32, transform);
SAFE_PARCEL(output.writeBool, transformToDisplayInverse);
@@ -207,9 +208,7 @@
color.g = tmpFloat;
SAFE_PARCEL(input.readFloat, &tmpFloat);
color.b = tmpFloat;
-#ifndef NO_INPUT
- SAFE_PARCEL(inputHandle->readFromParcel, &input);
-#endif
+ SAFE_PARCEL(windowInfoHandle->readFromParcel, &input);
SAFE_PARCEL(input.read, transparentRegion);
SAFE_PARCEL(input.readUint32, &transform);
@@ -318,6 +317,7 @@
DisplayState::DisplayState()
: what(0),
layerStack(0),
+ flags(0),
layerStackSpaceRect(Rect::EMPTY_RECT),
orientedDisplaySpaceRect(Rect::EMPTY_RECT),
width(0),
@@ -328,6 +328,7 @@
SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(surface));
SAFE_PARCEL(output.writeUint32, what);
SAFE_PARCEL(output.writeUint32, layerStack);
+ SAFE_PARCEL(output.writeUint32, flags);
SAFE_PARCEL(output.writeUint32, toRotationInt(orientation));
SAFE_PARCEL(output.write, layerStackSpaceRect);
SAFE_PARCEL(output.write, orientedDisplaySpaceRect);
@@ -344,6 +345,7 @@
SAFE_PARCEL(input.readUint32, &what);
SAFE_PARCEL(input.readUint32, &layerStack);
+ SAFE_PARCEL(input.readUint32, &flags);
uint32_t tmpUint = 0;
SAFE_PARCEL(input.readUint32, &tmpUint);
orientation = ui::toRotation(tmpUint);
@@ -364,6 +366,10 @@
what |= eLayerStackChanged;
layerStack = other.layerStack;
}
+ if (other.what & eFlagsChanged) {
+ what |= eFlagsChanged;
+ flags = other.flags;
+ }
if (other.what & eDisplayProjectionChanged) {
what |= eDisplayProjectionChanged;
orientation = other.orientation;
@@ -487,14 +493,10 @@
if (other.what & eHasListenerCallbacksChanged) {
what |= eHasListenerCallbacksChanged;
}
-
-#ifndef NO_INPUT
if (other.what & eInputInfoChanged) {
what |= eInputInfoChanged;
- inputHandle = new InputWindowHandle(*other.inputHandle);
+ windowInfoHandle = new WindowInfoHandle(*other.windowInfoHandle);
}
-#endif
-
if (other.what & eCachedBufferChanged) {
what |= eCachedBufferChanged;
cachedBuffer = other.cachedBuffer;
@@ -558,10 +560,13 @@
what |= eDestinationFrameChanged;
destinationFrame = other.destinationFrame;
}
+ if (other.what & eProducerDisconnect) {
+ what |= eProducerDisconnect;
+ }
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
- "other.what=0x%" PRIu64 " what=0x%" PRIu64,
- other.what, what);
+ "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
+ other.what, what, (other.what & what) ^ other.what);
}
}
@@ -593,11 +598,9 @@
bool InputWindowCommands::merge(const InputWindowCommands& other) {
bool changes = false;
-#ifndef NO_INPUT
changes |= !other.focusRequests.empty();
focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()),
std::make_move_iterator(other.focusRequests.end()));
-#endif
changes |= other.syncInputWindows && !syncInputWindows;
syncInputWindows |= other.syncInputWindows;
return changes;
@@ -605,31 +608,23 @@
bool InputWindowCommands::empty() const {
bool empty = true;
-#ifndef NO_INPUT
empty = focusRequests.empty() && !syncInputWindows;
-#endif
return empty;
}
void InputWindowCommands::clear() {
-#ifndef NO_INPUT
focusRequests.clear();
-#endif
syncInputWindows = false;
}
status_t InputWindowCommands::write(Parcel& output) const {
-#ifndef NO_INPUT
SAFE_PARCEL(output.writeParcelableVector, focusRequests);
-#endif
SAFE_PARCEL(output.writeBool, syncInputWindows);
return NO_ERROR;
}
status_t InputWindowCommands::read(const Parcel& input) {
-#ifndef NO_INPUT
SAFE_PARCEL(input.readParcelableVector, &focusRequests);
-#endif
SAFE_PARCEL(input.readBool, &syncInputWindows);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 96da8ef..4dd8cb5 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -39,14 +39,11 @@
#include <gui/LayerState.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
+#include <gui/WindowInfo.h>
#include <private/gui/ParcelUtils.h>
#include <ui/DisplayMode.h>
#include <ui/DynamicDisplayInfo.h>
-#ifndef NO_INPUT
-#include <input/InputWindow.h>
-#endif
-
#include <private/gui/ComposerService.h>
// This server size should always be smaller than the server cache size
@@ -54,6 +51,9 @@
namespace android {
+using gui::FocusRequest;
+using gui::WindowInfo;
+using gui::WindowInfoHandle;
using ui::ColorMode;
// ---------------------------------------------------------------------------
@@ -1491,16 +1491,14 @@
return *this;
}
-#ifndef NO_INPUT
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(
- const sp<SurfaceControl>& sc,
- const InputWindowInfo& info) {
+ const sp<SurfaceControl>& sc, const WindowInfo& info) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
- s->inputHandle = new InputWindowHandle(info);
+ s->windowInfoHandle = new WindowInfoHandle(info);
s->what |= layer_state_t::eInputInfoChanged;
return *this;
}
@@ -1516,8 +1514,6 @@
return *this;
}
-#endif
-
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform(
const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) {
layer_state_t* s = getLayerState(sc);
@@ -1758,6 +1754,12 @@
s.what |= DisplayState::eLayerStackChanged;
}
+void SurfaceComposerClient::Transaction::setDisplayFlags(const sp<IBinder>& token, uint32_t flags) {
+ DisplayState& s(getDisplayState(token));
+ s.flags = flags;
+ s.what |= DisplayState::eFlagsChanged;
+}
+
void SurfaceComposerClient::Transaction::setDisplayProjection(const sp<IBinder>& token,
ui::Rotation orientation,
const Rect& layerStackRect,
@@ -2163,12 +2165,12 @@
return s->captureDisplay(captureArgs, captureListener);
}
-status_t ScreenshotClient::captureDisplay(uint64_t displayOrLayerStack,
+status_t ScreenshotClient::captureDisplay(DisplayId displayId,
const sp<IScreenCaptureListener>& captureListener) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == nullptr) return NO_INIT;
- return s->captureDisplay(displayOrLayerStack, captureListener);
+ return s->captureDisplay(displayId, captureListener);
}
status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
diff --git a/libs/input/InputWindow.cpp b/libs/gui/WindowInfo.cpp
similarity index 79%
rename from libs/input/InputWindow.cpp
rename to libs/gui/WindowInfo.cpp
index 9947720..ff0bb8a 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -15,43 +15,40 @@
*/
#include <type_traits>
-#define LOG_TAG "InputWindow"
+#define LOG_TAG "WindowInfo"
#define LOG_NDEBUG 0
#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
-#include <input/InputTransport.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
#include <log/log.h>
-namespace android {
+namespace android::gui {
-
-// --- InputWindowInfo ---
-void InputWindowInfo::addTouchableRegion(const Rect& region) {
+// --- WindowInfo ---
+void WindowInfo::addTouchableRegion(const Rect& region) {
touchableRegion.orSelf(region);
}
-bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
- return touchableRegion.contains(x,y);
+bool WindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
+ return touchableRegion.contains(x, y);
}
-bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
- return x >= frameLeft && x < frameRight
- && y >= frameTop && y < frameBottom;
+bool WindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
+ return x >= frameLeft && x < frameRight && y >= frameTop && y < frameBottom;
}
-bool InputWindowInfo::supportsSplitTouch() const {
+bool WindowInfo::supportsSplitTouch() const {
return flags.test(Flag::SPLIT_TOUCH);
}
-bool InputWindowInfo::overlaps(const InputWindowInfo* other) const {
- return frameLeft < other->frameRight && frameRight > other->frameLeft
- && frameTop < other->frameBottom && frameBottom > other->frameTop;
+bool WindowInfo::overlaps(const WindowInfo* other) const {
+ return frameLeft < other->frameRight && frameRight > other->frameLeft &&
+ frameTop < other->frameBottom && frameBottom > other->frameTop;
}
-bool InputWindowInfo::operator==(const InputWindowInfo& info) const {
+bool WindowInfo::operator==(const WindowInfo& info) const {
return info.token == token && info.id == id && info.name == name && info.flags == flags &&
info.type == type && info.dispatchingTimeout == dispatchingTimeout &&
info.frameLeft == frameLeft && info.frameTop == frameTop &&
@@ -69,7 +66,7 @@
info.applicationInfo == applicationInfo;
}
-status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const {
+status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
if (parcel == nullptr) {
ALOGE("%s: Null parcel", __func__);
return BAD_VALUE;
@@ -86,7 +83,7 @@
parcel->writeInt32(id) ?:
parcel->writeUtf8AsUtf16(name) ?:
parcel->writeInt32(flags.get()) ?:
- parcel->writeInt32(static_cast<std::underlying_type_t<InputWindowInfo::Type>>(type)) ?:
+ parcel->writeInt32(static_cast<std::underlying_type_t<WindowInfo::Type>>(type)) ?:
parcel->writeInt32(frameLeft) ?:
parcel->writeInt32(frameTop) ?:
parcel->writeInt32(frameRight) ?:
@@ -122,7 +119,7 @@
return status;
}
-status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) {
+status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
if (parcel == nullptr) {
ALOGE("%s: Null parcel", __func__);
return BAD_VALUE;
@@ -176,11 +173,13 @@
touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
inputFeatures = Flags<Feature>(parcel->readInt32());
+ // clang-format off
status = parcel->readInt32(&displayId) ?:
parcel->readInt32(&portalToDisplayId) ?:
applicationInfo.readFromParcel(parcel) ?:
parcel->read(touchableRegion) ?:
parcel->readBool(&replaceTouchableRegionWithCrop);
+ // clang-format on
if (status != OK) {
return status;
@@ -192,33 +191,33 @@
return OK;
}
-// --- InputWindowHandle ---
+// --- WindowInfoHandle ---
-InputWindowHandle::InputWindowHandle() {}
+WindowInfoHandle::WindowInfoHandle() {}
-InputWindowHandle::~InputWindowHandle() {}
+WindowInfoHandle::~WindowInfoHandle() {}
-InputWindowHandle::InputWindowHandle(const InputWindowHandle& other) : mInfo(other.mInfo) {}
+WindowInfoHandle::WindowInfoHandle(const WindowInfoHandle& other) : mInfo(other.mInfo) {}
-InputWindowHandle::InputWindowHandle(const InputWindowInfo& other) : mInfo(other) {}
+WindowInfoHandle::WindowInfoHandle(const WindowInfo& other) : mInfo(other) {}
-status_t InputWindowHandle::writeToParcel(android::Parcel* parcel) const {
+status_t WindowInfoHandle::writeToParcel(android::Parcel* parcel) const {
return mInfo.writeToParcel(parcel);
}
-status_t InputWindowHandle::readFromParcel(const android::Parcel* parcel) {
+status_t WindowInfoHandle::readFromParcel(const android::Parcel* parcel) {
return mInfo.readFromParcel(parcel);
}
-void InputWindowHandle::releaseChannel() {
+void WindowInfoHandle::releaseChannel() {
mInfo.token.clear();
}
-sp<IBinder> InputWindowHandle::getToken() const {
+sp<IBinder> WindowInfoHandle::getToken() const {
return mInfo.token;
}
-void InputWindowHandle::updateFrom(sp<InputWindowHandle> handle) {
+void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
mInfo = handle->mInfo;
}
-} // namespace android
+} // namespace android::gui
diff --git a/libs/input/android/FocusRequest.aidl b/libs/gui/android/gui/FocusRequest.aidl
similarity index 98%
rename from libs/input/android/FocusRequest.aidl
rename to libs/gui/android/gui/FocusRequest.aidl
index 8812d34..9018635 100644
--- a/libs/input/android/FocusRequest.aidl
+++ b/libs/gui/android/gui/FocusRequest.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android;
+package android.gui;
/** @hide */
parcelable FocusRequest {
diff --git a/libs/input/android/InputApplicationInfo.aidl b/libs/gui/android/gui/InputApplicationInfo.aidl
similarity index 96%
rename from libs/input/android/InputApplicationInfo.aidl
rename to libs/gui/android/gui/InputApplicationInfo.aidl
index 9336039..c0fd666 100644
--- a/libs/input/android/InputApplicationInfo.aidl
+++ b/libs/gui/android/gui/InputApplicationInfo.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android;
+package android.gui;
parcelable InputApplicationInfo {
@nullable IBinder token;
diff --git a/libs/input/android/os/TouchOcclusionMode.aidl b/libs/gui/android/gui/TouchOcclusionMode.aidl
similarity index 98%
rename from libs/input/android/os/TouchOcclusionMode.aidl
rename to libs/gui/android/gui/TouchOcclusionMode.aidl
index 106f159..d91d052 100644
--- a/libs/input/android/os/TouchOcclusionMode.aidl
+++ b/libs/gui/android/gui/TouchOcclusionMode.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.os;
+package android.gui;
/**
diff --git a/libs/input/android/InputWindowInfo.aidl b/libs/gui/android/gui/WindowInfo.aidl
similarity index 81%
rename from libs/input/android/InputWindowInfo.aidl
rename to libs/gui/android/gui/WindowInfo.aidl
index eeaf400..2c85d15 100644
--- a/libs/input/android/InputWindowInfo.aidl
+++ b/libs/gui/android/gui/WindowInfo.aidl
@@ -1,5 +1,4 @@
-/* //device/java/android/android/view/InputChannel.aidl
-**
+/*
** Copyright 2020, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +14,6 @@
** limitations under the License.
*/
-package android;
+package android.gui;
-parcelable InputWindowInfo cpp_header "input/InputWindow.h";
+parcelable WindowInfo cpp_header "gui/WindowInfo.h";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 2a3f6a4..c0a2335 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -24,9 +24,9 @@
#include <android/gui/ITunnelModeEnabledListener.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
+#include <ftl/Flags.h>
#include <gui/FrameTimelineInfo.h>
#include <gui/ITransactionCompletedListener.h>
-#include <input/Flags.h>
#include <math/vec4.h>
#include <stdint.h>
#include <sys/types.h>
@@ -115,6 +115,11 @@
using EventRegistrationFlags = Flags<EventRegistration>;
+ template <typename T>
+ struct SpHash {
+ size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); }
+ };
+
/*
* Create a connection with SurfaceFlinger.
*/
@@ -238,24 +243,17 @@
* The subregion can be optionally rotated. It will also be scaled to
* match the size of the output buffer.
*/
- virtual status_t captureDisplay(const DisplayCaptureArgs& args,
- const sp<IScreenCaptureListener>& captureListener) = 0;
+ virtual status_t captureDisplay(const DisplayCaptureArgs&,
+ const sp<IScreenCaptureListener>&) = 0;
- virtual status_t captureDisplay(uint64_t displayOrLayerStack,
- const sp<IScreenCaptureListener>& captureListener) = 0;
-
- template <class AA>
- struct SpHash {
- size_t operator()(const sp<AA>& k) const { return std::hash<AA*>()(k.get()); }
- };
+ virtual status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) = 0;
/**
* Capture a subtree of the layer hierarchy, potentially ignoring the root node.
* This requires READ_FRAME_BUFFER permission. This function will fail if there
* is a secure window on screen
*/
- virtual status_t captureLayers(const LayerCaptureArgs& args,
- const sp<IScreenCaptureListener>& captureListener) = 0;
+ virtual status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) = 0;
/* Clears the frame statistics for animations.
*
diff --git a/include/input/InputApplication.h b/libs/gui/include/gui/InputApplication.h
similarity index 84%
rename from include/input/InputApplication.h
rename to libs/gui/include/gui/InputApplication.h
index 8e4fe79..679c2a1 100644
--- a/include/input/InputApplication.h
+++ b/libs/gui/include/gui/InputApplication.h
@@ -19,17 +19,17 @@
#include <string>
-#include <android/InputApplicationInfo.h>
+#include <android/gui/InputApplicationInfo.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
-#include <input/Input.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
namespace android {
+
/*
* Handle for an application that can receive input.
*
@@ -38,13 +38,9 @@
*/
class InputApplicationHandle {
public:
- inline const InputApplicationInfo* getInfo() const {
- return &mInfo;
- }
+ inline const gui::InputApplicationInfo* getInfo() const { return &mInfo; }
- inline std::string getName() const {
- return !mInfo.name.empty() ? mInfo.name : "<invalid>";
- }
+ inline std::string getName() const { return !mInfo.name.empty() ? mInfo.name : "<invalid>"; }
inline std::chrono::nanoseconds getDispatchingTimeout(
std::chrono::nanoseconds defaultValue) const {
@@ -52,9 +48,7 @@
: defaultValue;
}
- inline sp<IBinder> getApplicationToken() const {
- return mInfo.token;
- }
+ inline sp<IBinder> getApplicationToken() const { return mInfo.token; }
bool operator==(const InputApplicationHandle& other) const {
return getName() == other.getName() && getApplicationToken() == other.getApplicationToken();
@@ -77,7 +71,7 @@
InputApplicationHandle() = default;
virtual ~InputApplicationHandle() = default;
- InputApplicationInfo mInfo;
+ gui::InputApplicationInfo mInfo;
};
} // namespace android
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 3e57ff6..b27d9cf 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -26,14 +26,12 @@
#include <gui/ITransactionCompletedListener.h>
#include <math/mat4.h>
-#ifndef NO_INPUT
-#include <android/FocusRequest.h>
-#include <input/InputWindow.h>
-#endif
+#include <android/gui/FocusRequest.h>
#include <gui/ISurfaceComposer.h>
#include <gui/LayerMetadata.h>
#include <gui/SurfaceControl.h>
+#include <gui/WindowInfo.h>
#include <math/vec3.h>
#include <ui/BlurRegion.h>
#include <ui/GraphicTypes.h>
@@ -178,9 +176,7 @@
mat4 colorTransform;
std::vector<BlurRegion> blurRegions;
-#ifndef NO_INPUT
- sp<InputWindowHandle> inputHandle = new InputWindowHandle();
-#endif
+ sp<gui::WindowInfoHandle> windowInfoHandle = new gui::WindowInfoHandle();
client_cache_t cachedBuffer;
@@ -259,7 +255,8 @@
eSurfaceChanged = 0x01,
eLayerStackChanged = 0x02,
eDisplayProjectionChanged = 0x04,
- eDisplaySizeChanged = 0x08
+ eDisplaySizeChanged = 0x08,
+ eFlagsChanged = 0x10
};
DisplayState();
@@ -269,6 +266,7 @@
sp<IBinder> token;
sp<IGraphicBufferProducer> surface;
uint32_t layerStack;
+ uint32_t flags;
// These states define how layers are projected onto the physical display.
//
@@ -292,9 +290,7 @@
};
struct InputWindowCommands {
-#ifndef NO_INPUT
- std::vector<FocusRequest> focusRequests;
-#endif
+ std::vector<gui::FocusRequest> focusRequests;
bool syncInputWindows{false};
// Merges the passed in commands and returns true if there were any changes.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index baa0567..38eb31e 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -502,11 +502,9 @@
// Set the framenumber generated by the graphics producer to mimic BufferQueue behaviour.
Transaction& setFrameNumber(const sp<SurfaceControl>& sc, uint64_t frameNumber);
-#ifndef NO_INPUT
- Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
- Transaction& setFocusedWindow(const FocusRequest& request);
+ Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const gui::WindowInfo& info);
+ Transaction& setFocusedWindow(const gui::FocusRequest& request);
Transaction& syncInputWindows();
-#endif
// Set a color transform matrix on the given layer on the built-in display.
Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
@@ -569,6 +567,8 @@
void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack);
+ void setDisplayFlags(const sp<IBinder>& token, uint32_t flags);
+
/* setDisplayProjection() defines the projection of layer stacks
* to a given display.
*
@@ -634,12 +634,9 @@
class ScreenshotClient {
public:
- static status_t captureDisplay(const DisplayCaptureArgs& captureArgs,
- const sp<IScreenCaptureListener>& captureListener);
- static status_t captureDisplay(uint64_t displayOrLayerStack,
- const sp<IScreenCaptureListener>& captureListener);
- static status_t captureLayers(const LayerCaptureArgs& captureArgs,
- const sp<IScreenCaptureListener>& captureListener);
+ static status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&);
+ static status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&);
+ static status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&);
};
// ---------------------------------------------------------------------------
diff --git a/include/input/InputWindow.h b/libs/gui/include/gui/WindowInfo.h
similarity index 89%
rename from include/input/InputWindow.h
rename to libs/gui/include/gui/WindowInfo.h
index 121be6d..b0c631a 100644
--- a/include/input/InputWindow.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -14,15 +14,13 @@
* limitations under the License.
*/
-#ifndef _UI_INPUT_WINDOW_H
-#define _UI_INPUT_WINDOW_H
+#pragma once
-#include <android/os/TouchOcclusionMode.h>
+#include <android/gui/TouchOcclusionMode.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
-#include <input/Flags.h>
-#include <input/Input.h>
-#include <input/InputTransport.h>
+#include <ftl/Flags.h>
+#include <gui/constants.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/Transform.h>
@@ -31,15 +29,13 @@
#include "InputApplication.h"
-using android::os::TouchOcclusionMode;
-
-namespace android {
+namespace android::gui {
/*
* Describes the properties of a window that can receive input.
*/
-struct InputWindowInfo : public Parcelable {
- InputWindowInfo() = default;
+struct WindowInfo : public Parcelable {
+ WindowInfo() = default;
// Window flags from WindowManager.LayoutParams
enum class Flag : uint32_t {
@@ -168,9 +164,12 @@
// Transform applied to individual windows.
ui::Transform transform;
+ // Display orientation. Used for compatibility raw coordinates.
+ uint32_t displayOrientation = ui::Transform::ROT_0;
+
// Display size in its natural rotation. Used to rotate raw coordinates for compatibility.
- int32_t displayWidth = AMOTION_EVENT_INVALID_DISPLAY_SIZE;
- int32_t displayHeight = AMOTION_EVENT_INVALID_DISPLAY_SIZE;
+ int32_t displayWidth = 0;
+ int32_t displayHeight = 0;
/*
* This is filled in by the WM relative to the frame and then translated
@@ -206,9 +205,9 @@
bool supportsSplitTouch() const;
- bool overlaps(const InputWindowInfo* other) const;
+ bool overlaps(const WindowInfo* other) const;
- bool operator==(const InputWindowInfo& inputChannel) const;
+ bool operator==(const WindowInfo& inputChannel) const;
status_t writeToParcel(android::Parcel* parcel) const override;
@@ -221,13 +220,13 @@
* Used by the native input dispatcher to indirectly refer to the window manager objects
* that describe a window.
*/
-class InputWindowHandle : public RefBase {
+class WindowInfoHandle : public RefBase {
public:
- explicit InputWindowHandle();
- InputWindowHandle(const InputWindowHandle& other);
- InputWindowHandle(const InputWindowInfo& other);
+ explicit WindowInfoHandle();
+ WindowInfoHandle(const WindowInfoHandle& other);
+ WindowInfoHandle(const WindowInfo& other);
- inline const InputWindowInfo* getInfo() const { return &mInfo; }
+ inline const WindowInfo* getInfo() const { return &mInfo; }
sp<IBinder> getToken() const;
@@ -257,7 +256,7 @@
/**
* Updates from another input window handle.
*/
- void updateFrom(const sp<InputWindowHandle> handle);
+ void updateFrom(const sp<WindowInfoHandle> handle);
/**
* Releases the channel used by the associated information when it is
@@ -270,10 +269,8 @@
status_t writeToParcel(android::Parcel* parcel) const;
protected:
- virtual ~InputWindowHandle();
+ virtual ~WindowInfoHandle();
- InputWindowInfo mInfo;
+ WindowInfo mInfo;
};
-} // namespace android
-
-#endif // _UI_INPUT_WINDOW_H
+} // namespace android::gui
\ No newline at end of file
diff --git a/libs/gui/include/gui/constants.h b/libs/gui/include/gui/constants.h
new file mode 100644
index 0000000..8eab378
--- /dev/null
+++ b/libs/gui/include/gui/constants.h
@@ -0,0 +1,37 @@
+/*
+ * 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 <stdint.h>
+
+namespace android {
+
+/**
+ * Invalid value for display size. Used when display size isn't available.
+ */
+constexpr int32_t INVALID_DISPLAY_SIZE = 0;
+
+enum {
+ /* Used when an event is not associated with any display.
+ * Typically used for non-pointer events. */
+ ADISPLAY_ID_NONE = -1,
+
+ /* The default display id. */
+ ADISPLAY_ID_DEFAULT = 0,
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index c801c62..3d26c3d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -43,6 +43,7 @@
"SurfaceTextureMultiContextGL_test.cpp",
"Surface_test.cpp",
"TextureRenderer.cpp",
+ "WindowInfo_test.cpp",
],
shared_libs: [
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 49c44a7..fc84c1b 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -37,9 +37,9 @@
#include <gui/SurfaceControl.h>
#include <android/os/IInputFlinger.h>
+#include <gui/WindowInfo.h>
#include <input/Input.h>
#include <input/InputTransport.h>
-#include <input/InputWindow.h>
#include <ui/DisplayMode.h>
#include <ui/Rect.h>
@@ -49,6 +49,11 @@
using android::hardware::graphics::common::V1_1::BufferUsage;
+using android::gui::FocusRequest;
+using android::gui::InputApplicationInfo;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+
namespace android::test {
using Transaction = SurfaceComposerClient::Transaction;
@@ -221,8 +226,8 @@
void populateInputInfo(int width, int height) {
mInputInfo.token = mClientChannel->getConnectionToken();
mInputInfo.name = "Test info";
- mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
- mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
+ mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
+ mInputInfo.type = WindowInfo::Type::BASE_APPLICATION;
mInputInfo.dispatchingTimeout = 5s;
mInputInfo.globalScaleFactor = 1.0;
mInputInfo.focusable = true;
@@ -249,7 +254,7 @@
std::shared_ptr<InputChannel> mClientChannel;
sp<IInputFlinger> mInputFlinger;
- InputWindowInfo mInputInfo;
+ WindowInfo mInputInfo;
PreallocatedInputEventFactory mInputEventFactory;
InputConsumer* mInputConsumer;
@@ -686,7 +691,7 @@
// Add non touchable window to fully cover touchable window. Window behind gets touch, but
// with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
nonTouchableSurface->mInputInfo.ownerUid = 22222;
// Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
// the default obscured/untrusted touch filter introduced in S.
@@ -706,8 +711,8 @@
// AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
- parentSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
nonTouchableSurface->mInputInfo.ownerUid = 22222;
parentSurface->mInputInfo.ownerUid = 22222;
nonTouchableSurface->showAt(0, 0);
@@ -730,8 +735,8 @@
// the touchable window. Window behind gets touch with no obscured flags.
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
- parentSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
nonTouchableSurface->mInputInfo.ownerUid = 22222;
parentSurface->mInputInfo.ownerUid = 22222;
nonTouchableSurface->showAt(0, 0);
@@ -751,7 +756,7 @@
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
bufferSurface->mInputInfo.ownerUid = 22222;
surface->showAt(10, 10);
@@ -766,7 +771,7 @@
std::unique_ptr<BlastInputSurface> bufferSurface =
BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
bufferSurface->mInputInfo.ownerUid = 22222;
surface->showAt(10, 10);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 59b0c04..8d7a356 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -752,21 +752,19 @@
}
status_t setActiveColorMode(const sp<IBinder>& /*display*/,
ColorMode /*colorMode*/) override { return NO_ERROR; }
- status_t captureDisplay(const DisplayCaptureArgs& /* captureArgs */,
- const sp<IScreenCaptureListener>& /* captureListener */) override {
- return NO_ERROR;
- }
void setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {}
void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {}
- status_t captureDisplay(uint64_t /*displayOrLayerStack*/,
- const sp<IScreenCaptureListener>& /* captureListener */) override {
+
+ status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&) override {
return NO_ERROR;
}
- virtual status_t captureLayers(
- const LayerCaptureArgs& /* captureArgs */,
- const sp<IScreenCaptureListener>& /* captureListener */) override {
+ status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) override {
return NO_ERROR;
}
+ status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) override {
+ return NO_ERROR;
+ }
+
status_t clearAnimationFrameStats() override { return NO_ERROR; }
status_t getAnimationFrameStats(FrameStats* /*outStats*/) const override {
return NO_ERROR;
diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/gui/tests/WindowInfo_test.cpp
similarity index 88%
rename from libs/input/tests/InputWindow_test.cpp
rename to libs/gui/tests/WindowInfo_test.cpp
index 493f2f4..58f3981 100644
--- a/libs/input/tests/InputWindow_test.cpp
+++ b/libs/gui/tests/WindowInfo_test.cpp
@@ -19,16 +19,20 @@
#include <binder/Binder.h>
#include <binder/Parcel.h>
-#include <input/InputWindow.h>
-#include <input/InputTransport.h>
+#include <gui/WindowInfo.h>
using std::chrono_literals::operator""s;
namespace android {
+
+using gui::InputApplicationInfo;
+using gui::TouchOcclusionMode;
+using gui::WindowInfo;
+
namespace test {
-TEST(InputWindowInfo, ParcellingWithoutToken) {
- InputWindowInfo i, i2;
+TEST(WindowInfo, ParcellingWithoutToken) {
+ WindowInfo i, i2;
i.token = nullptr;
Parcel p;
@@ -38,14 +42,14 @@
ASSERT_TRUE(i2.token == nullptr);
}
-TEST(InputWindowInfo, Parcelling) {
+TEST(WindowInfo, Parcelling) {
sp<IBinder> touchableRegionCropHandle = new BBinder();
- InputWindowInfo i;
+ WindowInfo i;
i.token = new BBinder();
i.id = 1;
i.name = "Foobar";
- i.flags = InputWindowInfo::Flag::SLIPPERY;
- i.type = InputWindowInfo::Type::INPUT_METHOD;
+ i.flags = WindowInfo::Flag::SLIPPERY;
+ i.type = WindowInfo::Type::INPUT_METHOD;
i.dispatchingTimeout = 12s;
i.frameLeft = 93;
i.frameTop = 34;
@@ -55,6 +59,7 @@
i.globalScaleFactor = 0.3;
i.alpha = 0.7;
i.transform.set({0.4, -1, 100, 0.5, 0, 40, 0, 0, 1});
+ i.displayOrientation = ui::Transform::ROT_0;
i.displayWidth = 1000;
i.displayHeight = 2000;
i.visible = false;
@@ -65,7 +70,7 @@
i.ownerPid = 19;
i.ownerUid = 24;
i.packageName = "com.example.package";
- i.inputFeatures = InputWindowInfo::Feature::DISABLE_USER_ACTIVITY;
+ i.inputFeatures = WindowInfo::Feature::DISABLE_USER_ACTIVITY;
i.displayId = 34;
i.portalToDisplayId = 2;
i.replaceTouchableRegionWithCrop = true;
@@ -77,7 +82,7 @@
Parcel p;
i.writeToParcel(&p);
p.setDataPosition(0);
- InputWindowInfo i2;
+ WindowInfo i2;
i2.readFromParcel(&p);
ASSERT_EQ(i.token, i2.token);
ASSERT_EQ(i.id, i2.id);
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index a63ec8f..02cf9eb 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -30,7 +30,6 @@
"android/os/IInputConstants.aidl",
"android/os/InputEventInjectionResult.aidl",
"android/os/InputEventInjectionSync.aidl",
- "android/os/TouchOcclusionMode.aidl",
],
}
@@ -79,16 +78,12 @@
android: {
srcs: [
"InputTransport.cpp",
- "InputWindow.cpp",
- "android/FocusRequest.aidl",
- "android/InputApplicationInfo.aidl",
"android/os/BlockUntrustedTouchesMode.aidl",
"android/os/IInputConstants.aidl",
"android/os/IInputFlinger.aidl",
"android/os/InputEventInjectionResult.aidl",
"android/os/InputEventInjectionSync.aidl",
"android/os/ISetInputWindowsListener.aidl",
- "android/os/TouchOcclusionMode.aidl",
],
export_shared_lib_headers: ["libbinder"],
@@ -99,6 +94,14 @@
"libui",
],
+ static_libs: [
+ "libgui_window_info_static",
+ ],
+
+ export_static_lib_headers: [
+ "libgui_window_info_static",
+ ],
+
sanitize: {
misc_undefined: ["integer"],
},
@@ -114,26 +117,30 @@
linux_glibc: {
srcs: [
"InputTransport.cpp",
- "InputWindow.cpp",
- "android/FocusRequest.aidl",
- "android/InputApplicationInfo.aidl",
"android/os/IInputConstants.aidl",
"android/os/IInputFlinger.aidl",
"android/os/ISetInputWindowsListener.aidl",
- "android/os/TouchOcclusionMode.aidl",
],
static_libs: [
"libhostgraphics",
+ "libgui_window_info_static",
],
shared_libs: [
"libbinder",
],
+
+ export_static_lib_headers: [
+ "libgui_window_info_static",
+ ],
},
},
aidl: {
local_include_dirs: ["."],
export_aidl_headers: true,
+ include_dirs: [
+ "frameworks/native/libs/gui",
+ ],
},
}
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 70ed438..53a8c4f 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -24,6 +24,7 @@
#include <string.h>
#include <android-base/stringprintf.h>
+#include <gui/constants.h>
#include <input/Input.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
@@ -65,14 +66,11 @@
return result;
}
-// Rotates the given point to the transform's orientation. If the display width and height are
+// Rotates the given point to the specified orientation. If the display width and height are
// provided, the point is rotated in the screen space. Otherwise, the point is rotated about the
// origin. This helper is used to avoid the extra overhead of creating new Transforms.
-vec2 rotatePoint(const ui::Transform& transform, float x, float y, int32_t displayWidth = 0,
+vec2 rotatePoint(uint32_t orientation, float x, float y, int32_t displayWidth = 0,
int32_t displayHeight = 0) {
- // 0x7 encapsulates all 3 rotations (see ui::Transform::RotationFlags)
- static const int ALL_ROTATIONS_MASK = 0x7;
- const uint32_t orientation = (transform.getOrientation() & ALL_ROTATIONS_MASK);
if (orientation == ui::Transform::ROT_0) {
return {x, y};
}
@@ -91,6 +89,19 @@
return xy;
}
+vec2 applyTransformWithoutTranslation(const ui::Transform& transform, float x, float y) {
+ const vec2 transformedXy = transform.transform(x, y);
+ const vec2 transformedOrigin = transform.transform(0, 0);
+ return transformedXy - transformedOrigin;
+}
+
+bool shouldDisregardWindowTranslation(uint32_t source) {
+ // Pointer events are the only type of events that refer to absolute coordinates on the display,
+ // so we should apply the entire window transform. For other types of events, we should make
+ // sure to not apply the window translation/offset.
+ return (source & AINPUT_SOURCE_CLASS_POINTER) == 0;
+}
+
} // namespace
const char* motionClassificationToString(MotionClassification classification) {
@@ -149,6 +160,9 @@
case AINPUT_EVENT_TYPE_DRAG: {
return "DRAG";
}
+ case AINPUT_EVENT_TYPE_TOUCH_MODE: {
+ return "TOUCH_MODE";
+ }
}
return "UNKNOWN";
}
@@ -305,10 +319,8 @@
scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
-}
-
-void PointerCoords::scale(float globalScaleFactor) {
- scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
+ scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_X, windowXScale);
+ scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_Y, windowYScale);
}
void PointerCoords::applyOffset(float xOffset, float yOffset) {
@@ -373,6 +385,15 @@
setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
+ if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_RELATIVE_X) ||
+ BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_RELATIVE_Y)) {
+ const ui::Transform rotation(transform.getOrientation());
+ const vec2 relativeXy = rotation.transform(getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, relativeXy.x);
+ setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);
+ }
+
if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_ORIENTATION)) {
const float val = getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(transform, val));
@@ -400,9 +421,9 @@
int32_t buttonState, MotionClassification classification,
const ui::Transform& transform, float xPrecision, float yPrecision,
float rawXCursorPosition, float rawYCursorPosition,
- int32_t displayWidth, int32_t displayHeight, nsecs_t downTime,
- nsecs_t eventTime, size_t pointerCount,
- const PointerProperties* pointerProperties,
+ uint32_t displayOrientation, int32_t displayWidth,
+ int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime,
+ size_t pointerCount, const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords) {
InputEvent::initialize(id, deviceId, source, displayId, hmac);
mAction = action;
@@ -417,6 +438,7 @@
mYPrecision = yPrecision;
mRawXCursorPosition = rawXCursorPosition;
mRawYCursorPosition = rawYCursorPosition;
+ mDisplayOrientation = displayOrientation;
mDisplayWidth = displayWidth;
mDisplayHeight = displayHeight;
mDownTime = downTime;
@@ -442,6 +464,7 @@
mYPrecision = other->mYPrecision;
mRawXCursorPosition = other->mRawXCursorPosition;
mRawYCursorPosition = other->mRawYCursorPosition;
+ mDisplayOrientation = other->mDisplayOrientation;
mDisplayWidth = other->mDisplayWidth;
mDisplayHeight = other->mDisplayHeight;
mDownTime = other->mDownTime;
@@ -509,25 +532,48 @@
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
// For compatibility, convert raw coordinates into "oriented screen space". Once app
// developers are educated about getRaw, we can consider removing this.
- const vec2 xy = rotatePoint(mTransform, coords->getX(), coords->getY(), mDisplayWidth,
- mDisplayHeight);
+ const vec2 xy = shouldDisregardWindowTranslation(mSource)
+ ? rotatePoint(mDisplayOrientation, coords->getX(), coords->getY())
+ : rotatePoint(mDisplayOrientation, coords->getX(), coords->getY(), mDisplayWidth,
+ mDisplayHeight);
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
+ if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
+ // For compatibility, since we convert raw coordinates into "oriented screen space", we
+ // need to convert the relative axes into the same orientation for consistency.
+ const vec2 relativeXy = rotatePoint(mDisplayOrientation,
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
+ }
+
return coords->getAxisValue(axis);
}
float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
- size_t historicalIndex) const {
+ size_t historicalIndex) const {
const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- const vec2 xy = mTransform.transform(coords->getXYValue());
+ const vec2 xy = shouldDisregardWindowTranslation(mSource)
+ ? applyTransformWithoutTranslation(mTransform, coords->getX(), coords->getY())
+ : mTransform.transform(coords->getXYValue());
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
+ if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
+ const vec2 relativeXy =
+ applyTransformWithoutTranslation(mTransform,
+ coords->getAxisValue(
+ AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(
+ AMOTION_EVENT_AXIS_RELATIVE_Y));
+ return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
+ }
+
return coords->getAxisValue(axis);
}
@@ -583,6 +629,13 @@
// Apply the transformation to all samples.
std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
[&transform](PointerCoords& c) { c.transform(transform); });
+
+ if (mRawXCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
+ mRawYCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
+ const vec2 cursor = transform.transform(mRawXCursorPosition, mRawYCursorPosition);
+ mRawXCursorPosition = cursor.x;
+ mRawYCursorPosition = cursor.y;
+ }
}
#ifdef __linux__
@@ -643,6 +696,7 @@
mYPrecision = parcel->readFloat();
mRawXCursorPosition = parcel->readFloat();
mRawYCursorPosition = parcel->readFloat();
+ mDisplayOrientation = parcel->readUint32();
mDisplayWidth = parcel->readInt32();
mDisplayHeight = parcel->readInt32();
mDownTime = parcel->readInt64();
@@ -704,6 +758,7 @@
parcel->writeFloat(mYPrecision);
parcel->writeFloat(mRawXCursorPosition);
parcel->writeFloat(mRawYCursorPosition);
+ parcel->writeUint32(mDisplayOrientation);
parcel->writeInt32(mDisplayWidth);
parcel->writeInt32(mDisplayHeight);
parcel->writeInt64(mDownTime);
@@ -831,6 +886,19 @@
mY = from.mY;
}
+// --- TouchModeEvent ---
+
+void TouchModeEvent::initialize(int32_t id, bool isInTouchMode) {
+ InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
+ ADISPLAY_ID_NONE, INVALID_HMAC);
+ mIsInTouchMode = isInTouchMode;
+}
+
+void TouchModeEvent::initialize(const TouchModeEvent& from) {
+ InputEvent::initialize(from);
+ mIsInTouchMode = from.mIsInTouchMode;
+}
+
// --- PooledInputEventFactory ---
PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
@@ -885,6 +953,15 @@
return event;
}
+TouchModeEvent* PooledInputEventFactory::createTouchModeEvent() {
+ if (mTouchModeEventPool.empty()) {
+ return new TouchModeEvent();
+ }
+ TouchModeEvent* event = mTouchModeEventPool.front().release();
+ mTouchModeEventPool.pop();
+ return event;
+}
+
void PooledInputEventFactory::recycle(InputEvent* event) {
switch (event->getType()) {
case AINPUT_EVENT_TYPE_KEY:
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 30c42a3..220c8e1 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -21,9 +21,9 @@
#include <ctype.h>
#include <android-base/stringprintf.h>
+#include <ftl/NamedEnum.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
-#include <input/NamedEnum.h>
using android::base::StringPrintf;
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index dd1c462..1e93dfb 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -33,8 +33,8 @@
#include <log/log.h>
#include <utils/Trace.h>
+#include <ftl/NamedEnum.h>
#include <input/InputTransport.h>
-#include <input/NamedEnum.h>
using android::base::StringPrintf;
@@ -116,6 +116,7 @@
case Type::FOCUS:
case Type::CAPTURE:
case Type::DRAG:
+ case Type::TOUCH_MODE:
return true;
case Type::TIMELINE: {
const nsecs_t gpuCompletedTime =
@@ -151,6 +152,8 @@
return sizeof(Header) + body.drag.size();
case Type::TIMELINE:
return sizeof(Header) + body.timeline.size();
+ case Type::TOUCH_MODE:
+ return sizeof(Header) + body.touchMode.size();
}
return sizeof(Header);
}
@@ -242,9 +245,11 @@
msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
// float yCursorPosition
msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
- // int32_t displayW
+ // uint32_t displayOrientation
+ msg->body.motion.displayOrientation = body.motion.displayOrientation;
+ // int32_t displayWidth
msg->body.motion.displayWidth = body.motion.displayWidth;
- // int32_t displayH
+ // int32_t displayHeight
msg->body.motion.displayHeight = body.motion.displayHeight;
// uint32_t pointerCount
msg->body.motion.pointerCount = body.motion.pointerCount;
@@ -291,6 +296,10 @@
msg->body.timeline.graphicsTimeline = body.timeline.graphicsTimeline;
break;
}
+ case InputMessage::Type::TOUCH_MODE: {
+ msg->body.touchMode.eventId = body.touchMode.eventId;
+ msg->body.touchMode.isInTouchMode = body.touchMode.isInTouchMode;
+ }
}
}
@@ -533,9 +542,10 @@
std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
int32_t edgeFlags, int32_t metaState, int32_t buttonState,
MotionClassification classification, const ui::Transform& transform, float xPrecision,
- float yPrecision, float xCursorPosition, float yCursorPosition, int32_t displayWidth,
- int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
+ float yPrecision, float xCursorPosition, float yCursorPosition, uint32_t displayOrientation,
+ int32_t displayWidth, int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime,
+ uint32_t pointerCount, const PointerProperties* pointerProperties,
+ const PointerCoords* pointerCoords) {
if (ATRACE_ENABLED()) {
std::string message = StringPrintf(
"publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
@@ -593,6 +603,7 @@
msg.body.motion.yPrecision = yPrecision;
msg.body.motion.xCursorPosition = xCursorPosition;
msg.body.motion.yCursorPosition = yCursorPosition;
+ msg.body.motion.displayOrientation = displayOrientation;
msg.body.motion.displayWidth = displayWidth;
msg.body.motion.displayHeight = displayHeight;
msg.body.motion.downTime = downTime;
@@ -661,6 +672,22 @@
return mChannel->sendMessage(&msg);
}
+status_t InputPublisher::publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode) {
+ if (ATRACE_ENABLED()) {
+ std::string message =
+ StringPrintf("publishTouchModeEvent(inputChannel=%s, isInTouchMode=%s)",
+ mChannel->getName().c_str(), toString(isInTouchMode));
+ ATRACE_NAME(message.c_str());
+ }
+
+ InputMessage msg;
+ msg.header.type = InputMessage::Type::TOUCH_MODE;
+ msg.header.seq = seq;
+ msg.body.touchMode.eventId = eventId;
+ msg.body.touchMode.isInTouchMode = isInTouchMode;
+ return mChannel->sendMessage(&msg);
+}
+
android::base::Result<InputPublisher::ConsumerResponse> InputPublisher::receiveConsumerResponse() {
if (DEBUG_TRANSPORT_ACTIONS) {
ALOGD("channel '%s' publisher ~ %s", mChannel->getName().c_str(), __func__);
@@ -862,6 +889,16 @@
*outEvent = dragEvent;
break;
}
+
+ case InputMessage::Type::TOUCH_MODE: {
+ TouchModeEvent* touchModeEvent = factory->createTouchModeEvent();
+ if (!touchModeEvent) return NO_MEMORY;
+
+ initializeTouchModeEvent(touchModeEvent, &mMsg);
+ *outSeq = mMsg.header.seq;
+ *outEvent = touchModeEvent;
+ break;
+ }
}
}
return OK;
@@ -1361,9 +1398,13 @@
msg->body.motion.buttonState, msg->body.motion.classification, transform,
msg->body.motion.xPrecision, msg->body.motion.yPrecision,
msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
- msg->body.motion.displayWidth, msg->body.motion.displayHeight,
- msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
- pointerProperties, pointerCoords);
+ msg->body.motion.displayOrientation, msg->body.motion.displayWidth,
+ msg->body.motion.displayHeight, msg->body.motion.downTime,
+ msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
+}
+
+void InputConsumer::initializeTouchModeEvent(TouchModeEvent* event, const InputMessage* msg) {
+ event->initialize(msg->body.touchMode.eventId, msg->body.touchMode.isInTouchMode);
}
void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
@@ -1472,6 +1513,11 @@
presentTime);
break;
}
+ case InputMessage::Type::TOUCH_MODE: {
+ out += android::base::StringPrintf("isInTouchMode=%s",
+ toString(msg.body.touchMode.isInTouchMode));
+ break;
+ }
}
out += "\n";
}
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 44f3f34..3baeb55 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -28,10 +28,11 @@
#include <input/KeyCharacterMap.h>
#include <input/Keyboard.h>
-#include <utils/Log.h>
+#include <gui/constants.h>
#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
+#include <utils/Log.h>
#include <utils/Timers.h>
+#include <utils/Tokenizer.h>
// Enables debug output for the parser.
#define DEBUG_PARSER 0
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index fa5a541..c365ab0 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -19,10 +19,10 @@
#include <stdlib.h>
#include <android/keycodes.h>
+#include <ftl/NamedEnum.h>
#include <input/InputEventLabels.h>
#include <input/KeyLayoutMap.h>
#include <input/Keyboard.h>
-#include <input/NamedEnum.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/Timers.h>
diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl
index 1771d19..43b262f 100644
--- a/libs/input/android/os/IInputFlinger.aidl
+++ b/libs/input/android/os/IInputFlinger.aidl
@@ -16,9 +16,9 @@
package android.os;
-import android.FocusRequest;
import android.InputChannel;
-import android.InputWindowInfo;
+import android.gui.FocusRequest;
+import android.gui.WindowInfo;
import android.os.ISetInputWindowsListener;
/** @hide */
@@ -28,7 +28,7 @@
// ordering when needed.
// SurfaceFlinger calls this only every VSync, so overflow of binder's oneway buffer
// shouldn't be a concern.
- oneway void setInputWindows(in InputWindowInfo[] inputHandles,
+ oneway void setInputWindows(in WindowInfo[] windowInfoHandles,
in @nullable ISetInputWindowsListener setInputWindowsListener);
InputChannel createInputChannel(in @utf8InCpp String name);
void removeInputChannel(in IBinder connectionToken);
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 6ffc6a8..18ab1cb 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -11,26 +11,24 @@
cc_test {
name: "libinput_tests",
srcs: [
- "NamedEnum_test.cpp",
- "Flags_test.cpp",
"IdGenerator_test.cpp",
"InputChannel_test.cpp",
"InputDevice_test.cpp",
"InputEvent_test.cpp",
"InputPublisherAndConsumer_test.cpp",
- "InputWindow_test.cpp",
"TouchVideoFrame_test.cpp",
"VelocityTracker_test.cpp",
"VerifiedInputEvent_test.cpp",
],
+ static_libs: [
+ "libgui_window_info_static",
+ "libinput",
+ ],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
],
- static_libs: [
- "libinput",
- ],
shared_libs: [
"libbase",
"libbinder",
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 32b72ba..a2fa319 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -20,6 +20,7 @@
#include <attestation/HmacKeyManager.h>
#include <binder/Parcel.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <input/Input.h>
namespace android {
@@ -271,7 +272,7 @@
AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
MotionClassification::NONE, mTransform, 2.0f, 2.1f,
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties,
pointerCoords);
@@ -588,12 +589,12 @@
}
MotionEvent event;
ui::Transform identityTransform;
- event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_UNKNOWN, DISPLAY_ID,
+ event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
INVALID_HMAC, AMOTION_EVENT_ACTION_MOVE, 0 /*actionButton*/, 0 /*flags*/,
AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/, 2 /*yCursorPosition*/,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
pointerCoords);
float originalRawX = 0 + 3;
@@ -636,13 +637,17 @@
ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
}
-MotionEvent createTouchDownEvent(int x, int y, ui::Transform transform) {
+MotionEvent createTouchDownEvent(float x, float y, float dx, float dy,
+ const ui::Transform& transform,
+ uint32_t displayOrientation = ui::Transform::ROT_0) {
std::vector<PointerProperties> pointerProperties;
pointerProperties.push_back(PointerProperties{/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER});
std::vector<PointerCoords> pointerCoords;
pointerCoords.emplace_back().clear();
pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, dx);
+ pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, dy);
nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
MotionEvent event;
event.initialize(InputEvent::nextId(), /* deviceId */ 1, AINPUT_SOURCE_TOUCHSCREEN,
@@ -650,7 +655,8 @@
/* actionButton */ 0, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
/* buttonState */ 0, MotionClassification::NONE, transform,
/* xPrecision */ 0, /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, /* displayWidth */ 400,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, displayOrientation,
+ /* displayWidth */ 400,
/* displayHeight */ 800, eventTime, eventTime, pointerCoords.size(),
pointerProperties.data(), pointerCoords.data());
return event;
@@ -661,26 +667,56 @@
ui::Transform identity;
ui::Transform xform(ui::Transform::ROT_90, 800, 400);
xform.set(xform.tx() + 20, xform.ty() + 40);
- MotionEvent event = createTouchDownEvent(60, 100, xform);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
ASSERT_EQ(700, event.getRawX(0));
ASSERT_EQ(60, event.getRawY(0));
ASSERT_NE(event.getRawX(0), event.getX(0));
ASSERT_NE(event.getRawY(0), event.getY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
- MotionEvent changedEvent = createTouchDownEvent(60, 100, identity);
+ MotionEvent changedEvent = createTouchDownEvent(60, 100, 42, 96, identity);
const std::array<float, 9> rowMajor{xform[0][0], xform[1][0], xform[2][0],
xform[0][1], xform[1][1], xform[2][1],
xform[0][2], xform[1][2], xform[2][2]};
changedEvent.applyTransform(rowMajor);
// transformContent effectively rotates the raw coordinates, so those should now include
- // both rotation AND offset
+ // both rotation AND offset.
ASSERT_EQ(720, changedEvent.getRawX(0));
ASSERT_EQ(100, changedEvent.getRawY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
- // The transformed output should be the same then
+ // The transformed output should be the same then.
ASSERT_NEAR(event.getX(0), changedEvent.getX(0), 0.001);
ASSERT_NEAR(event.getY(0), changedEvent.getY(0), 0.001);
+ ASSERT_NEAR(event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0),
+ changedEvent.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0), 0.001);
+ ASSERT_NEAR(event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0),
+ changedEvent.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0), 0.001);
+}
+
+TEST_F(MotionEventTest, NonPointerSourcesAreNotTranslated) {
+ constexpr static auto NON_POINTER_SOURCES = {AINPUT_SOURCE_TRACKBALL,
+ AINPUT_SOURCE_MOUSE_RELATIVE,
+ AINPUT_SOURCE_JOYSTICK};
+ for (uint32_t source : NON_POINTER_SOURCES) {
+ // Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
+ ui::Transform xform(ui::Transform::ROT_90, 800, 400);
+ xform.set(xform.tx() + 20, xform.ty() + 40);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
+ event.setSource(source);
+
+ // Since this event comes from a non-pointer source, it should include rotation but not
+ // translation/offset.
+ ASSERT_EQ(-100, event.getX(0));
+ ASSERT_EQ(60, event.getY(0));
+ ASSERT_EQ(event.getRawX(0), event.getX(0));
+ ASSERT_EQ(event.getRawY(0), event.getY(0));
+ }
}
TEST_F(MotionEventTest, RawCompatTransform) {
@@ -688,11 +724,14 @@
// Make sure raw is raw regardless of transform translation.
ui::Transform xform;
xform.set(20, 40);
- MotionEvent event = createTouchDownEvent(60, 100, xform);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform);
ASSERT_EQ(60, event.getRawX(0));
ASSERT_EQ(100, event.getRawY(0));
ASSERT_NE(event.getRawX(0), event.getX(0));
ASSERT_NE(event.getRawY(0), event.getY(0));
+ // Relative values should not be modified.
+ ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
}
// Next check that getRaw contains rotation (for compatibility) but otherwise is still
@@ -701,29 +740,50 @@
// Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
ui::Transform xform(ui::Transform::ROT_90, 800, 400);
xform.set(xform.tx() + 20, xform.ty() + 40);
- MotionEvent event = createTouchDownEvent(60, 100, xform);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
ASSERT_EQ(700, event.getRawX(0));
ASSERT_EQ(60, event.getRawY(0));
ASSERT_NE(event.getRawX(0), event.getX(0));
ASSERT_NE(event.getRawY(0), event.getY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
}
{
// Same as above, but check rotate-180.
ui::Transform xform(ui::Transform::ROT_180, 400, 800);
xform.set(xform.tx() + 20, xform.ty() + 40);
- MotionEvent event = createTouchDownEvent(60, 100, xform);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_180);
ASSERT_EQ(340, event.getRawX(0));
ASSERT_EQ(700, event.getRawY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
}
{
// Same as above, but check rotate-270.
ui::Transform xform(ui::Transform::ROT_270, 800, 400);
xform.set(xform.tx() + 20, xform.ty() + 40);
- MotionEvent event = createTouchDownEvent(60, 100, xform);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_270);
ASSERT_EQ(100, event.getRawX(0));
ASSERT_EQ(340, event.getRawY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
+ }
+
+ {
+ // Finally, check that raw isn't effected by transform
+ ui::Transform xform(ui::Transform::ROT_270, 800, 400);
+ xform.set(xform.tx() + 20, xform.ty() + 40);
+ MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
+ ASSERT_EQ(700, event.getRawX(0));
+ ASSERT_EQ(60, event.getRawY(0));
+ // Relative values should be rotated but not translated.
+ ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+ ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
}
}
@@ -750,9 +810,9 @@
DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/,
- pointerCount, pointerProperties, pointerCoords);
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/,
+ 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(classification, event.getClassification());
}
}
@@ -772,10 +832,9 @@
event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID,
INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE,
AMETA_NONE, 0, MotionClassification::NONE, identityTransform, 0, 0,
- 280 /*xCursorPosition*/, 540 /*yCursorPosition*/,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- 0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
- pointerCoords);
+ 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/,
+ pointerCount, pointerProperties, pointerCoords);
event.offsetLocation(20, 60);
ASSERT_EQ(280, event.getRawXCursorPosition());
ASSERT_EQ(540, event.getRawYCursorPosition());
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index a2cfaa1..8db5bf1 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -23,6 +23,7 @@
#include <attestation/HmacKeyManager.h>
#include <cutils/ashmem.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <input/InputTransport.h>
#include <utils/StopWatch.h>
#include <utils/Timers.h>
@@ -55,6 +56,7 @@
void PublishAndConsumeFocusEvent();
void PublishAndConsumeCaptureEvent();
void PublishAndConsumeDragEvent();
+ void PublishAndConsumeTouchModeEvent();
};
TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
@@ -162,6 +164,7 @@
constexpr float yPrecision = 0.5;
constexpr float xCursorPosition = 1.3;
constexpr float yCursorPosition = 50.6;
+ constexpr uint32_t displayOrientation = ui::Transform::ROT_0;
constexpr int32_t displayWidth = 1000;
constexpr int32_t displayHeight = 2000;
constexpr nsecs_t downTime = 3;
@@ -192,9 +195,9 @@
status = mPublisher->publishMotionEvent(seq, eventId, deviceId, source, displayId, hmac, action,
actionButton, flags, edgeFlags, metaState, buttonState,
classification, transform, xPrecision, yPrecision,
- xCursorPosition, yCursorPosition, displayWidth,
- displayHeight, downTime, eventTime, pointerCount,
- pointerProperties, pointerCoords);
+ xCursorPosition, yCursorPosition, displayOrientation,
+ displayWidth, displayHeight, downTime, eventTime,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status)
<< "publisher publishMotionEvent should return OK";
@@ -231,6 +234,7 @@
EXPECT_EQ(yCursorPosition, motionEvent->getRawYCursorPosition());
EXPECT_EQ(xCursorPosition * xScale + xOffset, motionEvent->getXCursorPosition());
EXPECT_EQ(yCursorPosition * yScale + yOffset, motionEvent->getYCursorPosition());
+ EXPECT_EQ(displayOrientation, motionEvent->getDisplayOrientation());
EXPECT_EQ(displayWidth, motionEvent->getDisplaySize().x);
EXPECT_EQ(displayHeight, motionEvent->getDisplaySize().y);
EXPECT_EQ(downTime, motionEvent->getDownTime());
@@ -410,6 +414,46 @@
<< "finished signal's consume time should be greater than publish time";
}
+void InputPublisherAndConsumerTest::PublishAndConsumeTouchModeEvent() {
+ status_t status;
+
+ constexpr uint32_t seq = 15;
+ int32_t eventId = InputEvent::nextId();
+ constexpr bool touchModeEnabled = true;
+ const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ status = mPublisher->publishTouchModeEvent(seq, eventId, touchModeEnabled);
+ ASSERT_EQ(OK, status) << "publisher publishTouchModeEvent should return OK";
+
+ uint32_t consumeSeq;
+ InputEvent* event;
+ status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
+ ASSERT_EQ(OK, status) << "consumer consume should return OK";
+
+ ASSERT_TRUE(event != nullptr) << "consumer should have returned non-NULL event";
+ ASSERT_EQ(AINPUT_EVENT_TYPE_TOUCH_MODE, event->getType())
+ << "consumer should have returned a touch mode event";
+
+ const TouchModeEvent& touchModeEvent = static_cast<const TouchModeEvent&>(*event);
+ EXPECT_EQ(seq, consumeSeq);
+ EXPECT_EQ(eventId, touchModeEvent.getId());
+ EXPECT_EQ(touchModeEnabled, touchModeEvent.isInTouchMode());
+
+ status = mConsumer->sendFinishedSignal(seq, true);
+ ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
+
+ Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
+ ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
+ ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
+ const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
+ ASSERT_EQ(seq, finish.seq)
+ << "receiveConsumerResponse should have returned the original sequence number";
+ ASSERT_TRUE(finish.handled)
+ << "receiveConsumerResponse should have set handled to consumer's reply";
+ ASSERT_GE(finish.consumeTime, publishTime)
+ << "finished signal's consume time should be greater than publish time";
+}
+
TEST_F(InputPublisherAndConsumerTest, SendTimeline) {
const int32_t inputEventId = 20;
std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
@@ -446,6 +490,10 @@
ASSERT_NO_FATAL_FAILURE(PublishAndConsumeDragEvent());
}
+TEST_F(InputPublisherAndConsumerTest, PublishTouchModeEvent_EndToEnd) {
+ ASSERT_NO_FATAL_FAILURE(PublishAndConsumeTouchModeEvent());
+}
+
TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenSequenceNumberIsZero_ReturnsError) {
status_t status;
const size_t pointerCount = 1;
@@ -460,8 +508,9 @@
status = mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
0, 0, 0, MotionClassification::NONE, identityTransform,
0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
+ pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -476,8 +525,9 @@
status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
0, 0, 0, MotionClassification::NONE, identityTransform,
0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
+ pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -497,8 +547,9 @@
status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
0, 0, 0, MotionClassification::NONE, identityTransform,
0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
+ pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -514,6 +565,7 @@
ASSERT_NO_FATAL_FAILURE(PublishAndConsumeDragEvent());
ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+ ASSERT_NO_FATAL_FAILURE(PublishAndConsumeTouchModeEvent());
}
} // namespace android
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index 5861d55..18289a5 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -74,10 +74,10 @@
CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 124);
CHECK_OFFSET(InputMessage::Body::Motion, xCursorPosition, 128);
CHECK_OFFSET(InputMessage::Body::Motion, yCursorPosition, 132);
- CHECK_OFFSET(InputMessage::Body::Motion, displayWidth, 136);
- CHECK_OFFSET(InputMessage::Body::Motion, displayHeight, 140);
- CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 144);
- CHECK_OFFSET(InputMessage::Body::Motion, empty3, 148);
+ CHECK_OFFSET(InputMessage::Body::Motion, displayOrientation, 136);
+ CHECK_OFFSET(InputMessage::Body::Motion, displayWidth, 140);
+ CHECK_OFFSET(InputMessage::Body::Motion, displayHeight, 144);
+ CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 148);
CHECK_OFFSET(InputMessage::Body::Motion, pointers, 152);
CHECK_OFFSET(InputMessage::Body::Focus, eventId, 0);
@@ -102,6 +102,10 @@
CHECK_OFFSET(InputMessage::Body::Timeline, eventId, 0);
CHECK_OFFSET(InputMessage::Body::Timeline, empty, 4);
CHECK_OFFSET(InputMessage::Body::Timeline, graphicsTimeline, 8);
+
+ CHECK_OFFSET(InputMessage::Body::TouchMode, eventId, 0);
+ CHECK_OFFSET(InputMessage::Body::TouchMode, isInTouchMode, 4);
+ CHECK_OFFSET(InputMessage::Body::TouchMode, empty, 5);
}
void TestHeaderSize() {
@@ -123,6 +127,7 @@
static_assert(sizeof(InputMessage::Body::Focus) == 8);
static_assert(sizeof(InputMessage::Body::Capture) == 8);
static_assert(sizeof(InputMessage::Body::Drag) == 16);
+ static_assert(sizeof(InputMessage::Body::TouchMode) == 8);
// Timeline
static_assert(GraphicsTimeline::SIZE == 2);
static_assert(sizeof(InputMessage::Body::Timeline) == 24);
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index aefc2ec..13e2b02 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -23,6 +23,7 @@
#include <android-base/stringprintf.h>
#include <attestation/HmacKeyManager.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <input/VelocityTracker.h>
using namespace std::chrono_literals;
@@ -183,8 +184,8 @@
AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/,
entry.eventTime.count(), pointerCount, properties, coords);
events.emplace_back(event);
diff --git a/libs/input/tests/VerifiedInputEvent_test.cpp b/libs/input/tests/VerifiedInputEvent_test.cpp
index f79098c..b29c9a4 100644
--- a/libs/input/tests/VerifiedInputEvent_test.cpp
+++ b/libs/input/tests/VerifiedInputEvent_test.cpp
@@ -16,6 +16,7 @@
#include <attestation/HmacKeyManager.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <input/Input.h>
namespace android {
@@ -46,10 +47,9 @@
INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0 /*actionButton*/, flags,
AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
MotionClassification::NONE, transform, 0.1 /*xPrecision*/, 0.2 /*yPrecision*/,
- 280 /*xCursorPosition*/, 540 /*yCursorPosition*/,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- 100 /*downTime*/, 200 /*eventTime*/, pointerCount, pointerProperties,
- pointerCoords);
+ 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 100 /*downTime*/,
+ 200 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
return event;
}
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 0edb213..6a14d4f 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -20,7 +20,6 @@
#include <android-base/thread_annotations.h>
#include <gui/DisplayEventDispatcher.h>
#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
#include <jni.h>
#include <private/android/choreographer.h>
#include <utils/Looper.h>
@@ -306,8 +305,9 @@
// Fortunately, these events are small so sending packets across the
// socket should be atomic across processes.
DisplayEventReceiver::Event event;
- event.header = DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
- PhysicalDisplayId(0), systemTime()};
+ event.header =
+ DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
+ PhysicalDisplayId::fromPort(0), systemTime()};
injectEvent(event);
}
}
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 79b47a1..e2f32e3 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -653,6 +653,8 @@
case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
return 4;
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ return 8;
default:
return 0;
}
@@ -696,6 +698,10 @@
"gralloc and AHardwareBuffer flags don't match");
static_assert(AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE == (uint64_t)BufferUsage::GPU_MIPMAP_COMPLETE,
"gralloc and AHardwareBuffer flags don't match");
+ static_assert(AHARDWAREBUFFER_USAGE_CAMERA_WRITE == (uint64_t)BufferUsage::CAMERA_OUTPUT,
+ "gralloc and AHardwareBuffer flags don't match");
+ static_assert(AHARDWAREBUFFER_USAGE_CAMERA_READ == (uint64_t)BufferUsage::CAMERA_INPUT,
+ "gralloc and AHardwareBuffer flags don't match");
return usage;
}
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index d93a84c..d5e7cb2 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -556,6 +556,7 @@
int32_t* _Nonnull outBytesPerPixel,
int32_t* _Nonnull outBytesPerStride) __INTRODUCED_IN(29);
+
/**
* Get the system wide unique id for an AHardwareBuffer.
*
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 50fe0b7..21931bb 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -91,6 +91,20 @@
AHARDWAREBUFFER_FORMAT_YCbCr_422_I = 0x14,
};
+/**
+ * Buffer usage flags.
+ */
+enum {
+ /* for future proofing, keep these in sync with hardware/gralloc.h */
+
+ /* The buffer will be written by the HW camera pipeline. */
+ AHARDWAREBUFFER_USAGE_CAMERA_WRITE = 2UL << 16,
+ /* The buffer will be read by the HW camera pipeline. */
+ AHARDWAREBUFFER_USAGE_CAMERA_READ = 4UL << 16,
+ /* Mask for the camera access values. */
+ AHARDWAREBUFFER_USAGE_CAMERA_MASK = 6UL << 16,
+};
+
__END_DECLS
#endif /* ANDROID_VNDK_NATIVEWINDOW_AHARDWAREBUFFER_H */
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 467f848..b1e1014 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -1156,10 +1156,6 @@
const mat4 projectionMatrix =
ui::Transform(display.orientation).asMatrix4() * mState.projectionMatrix;
- if (!display.clearRegion.isEmpty()) {
- glDisable(GL_BLEND);
- fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
- }
Mesh mesh = Mesh::Builder()
.setPrimitive(Mesh::TRIANGLE_FAN)
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 4cb1b42..14627ce 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -71,7 +71,7 @@
void cleanupPostRender() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
- void onPrimaryDisplaySizeChanged(ui::Size size) override {}
+ void onActiveDisplaySizeChanged(ui::Size size) override {}
EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
// Creates an output image for rendering to
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index 53fa622..d395d06 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -51,10 +51,6 @@
// dataspace, in non-linear space.
mat4 colorTransform = mat4();
- // Region that will be cleared to (0, 0, 0, 1) prior to rendering.
- // This is specified in layer-stack space.
- Region clearRegion = Region::INVALID_REGION;
-
// An additional orientation flag to be applied after clipping the output.
// By way of example, this may be used for supporting fullscreen screenshot
// capture of a device in landscape while the buffer is in portrait
@@ -68,8 +64,7 @@
static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
return lhs.physicalDisplay == rhs.physicalDisplay && lhs.clip == rhs.clip &&
lhs.maxLuminance == rhs.maxLuminance && lhs.outputDataspace == rhs.outputDataspace &&
- lhs.colorTransform == rhs.colorTransform &&
- lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.orientation == rhs.orientation;
+ lhs.colorTransform == rhs.colorTransform && lhs.orientation == rhs.orientation;
}
// Defining PrintTo helps with Google Tests.
@@ -84,9 +79,6 @@
PrintTo(settings.outputDataspace, os);
*os << "\n .colorTransform = " << settings.colorTransform;
*os << "\n .clearRegion = ";
- PrintTo(settings.clearRegion, os);
- *os << "\n .orientation = " << settings.orientation;
- *os << "\n}";
}
} // namespace renderengine
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 5964bc3..967cf5d 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -129,9 +129,9 @@
// Attempt to switch RenderEngine into and out of protectedContext mode
virtual void useProtectedContext(bool useProtectedContext) = 0;
- // Notify RenderEngine of changes to the dimensions of the primary display
+ // Notify RenderEngine of changes to the dimensions of the active display
// so that it can configure its internal caches accordingly.
- virtual void onPrimaryDisplaySizeChanged(ui::Size size) = 0;
+ virtual void onActiveDisplaySizeChanged(ui::Size size) = 0;
// Renders layers for a particular display via GPU composition. This method
// should be called for every display that needs to be rendered via the GPU.
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index a4aa9ea..0be3ba6 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -54,7 +54,7 @@
MOCK_METHOD0(cleanFramebufferCache, void());
MOCK_METHOD0(getContextPriority, int());
MOCK_METHOD0(supportsBackgroundBlur, bool());
- MOCK_METHOD1(onPrimaryDisplaySizeChanged, void(ui::Size));
+ MOCK_METHOD1(onActiveDisplaySizeChanged, void(ui::Size));
protected:
// mock renderengine still needs to implement these, but callers should never need to call them.
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 3c59f11..16b5884 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -812,28 +812,6 @@
canvas->clear(SK_ColorTRANSPARENT);
initCanvas(canvas, display);
- // TODO: clearRegion was required for SurfaceView when a buffer is not yet available but the
- // view is still on-screen. The clear region could be re-specified as a black color layer,
- // however.
- if (!display.clearRegion.isEmpty()) {
- ATRACE_NAME("ClearRegion");
- size_t numRects = 0;
- Rect const* rects = display.clearRegion.getArray(&numRects);
- SkIRect skRects[numRects];
- for (int i = 0; i < numRects; ++i) {
- skRects[i] =
- SkIRect::MakeLTRB(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
- }
- SkRegion clearRegion;
- SkPaint paint;
- sk_sp<SkShader> shader =
- SkShaders::Color(SkColor4f{.fR = 0., .fG = 0., .fB = 0., .fA = 1.0},
- toSkColorSpace(dstDataspace));
- paint.setShader(shader);
- clearRegion.setRects(skRects, numRects);
- canvas->drawRegion(clearRegion, paint);
- }
-
for (const auto& layer : layers) {
ATRACE_FORMAT("DrawLayer: %s", layer->name.c_str());
@@ -1398,7 +1376,7 @@
return value;
}
-void SkiaGLRenderEngine::onPrimaryDisplaySizeChanged(ui::Size size) {
+void SkiaGLRenderEngine::onActiveDisplaySizeChanged(ui::Size size) {
// This cache multiplier was selected based on review of cache sizes relative
// to the screen resolution. Looking at the worst case memory needed by blur (~1.5x),
// shadows (~1x), and general data structures (e.g. vertex buffers) we selected this as a
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index a852bbc..cc91948 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -67,7 +67,7 @@
void useProtectedContext(bool useProtectedContext) override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
void assertShadersCompiled(int numShaders) override;
- void onPrimaryDisplaySizeChanged(ui::Size size) override;
+ void onActiveDisplaySizeChanged(ui::Size size) override;
int reportShadersCompiled() override;
protected:
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 33e3773..ec47f96 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -524,10 +524,6 @@
void fillGreenColorBufferThenClearRegion();
- void clearLeftRegion();
-
- void clearRegion();
-
template <typename SourceVariant>
void drawShadow(const renderengine::LayerSettings& castingLayer,
const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
@@ -1195,28 +1191,6 @@
expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
}
-void RenderEngineTest::clearLeftRegion() {
- renderengine::DisplaySettings settings;
- settings.physicalDisplay = fullscreenRect();
- // Here logical space is 4x4
- settings.clip = Rect(4, 4);
- settings.clearRegion = Region(Rect(2, 4));
- std::vector<const renderengine::LayerSettings*> layers;
- // fake layer, without bounds should not render anything
- renderengine::LayerSettings layer;
- layers.push_back(&layer);
- invokeDraw(settings, layers);
-}
-
-void RenderEngineTest::clearRegion() {
- // Reuse mBuffer
- clearLeftRegion();
- expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 255);
- expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
- DEFAULT_DISPLAY_HEIGHT),
- 0, 0, 0, 0);
-}
-
template <typename SourceVariant>
void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
const renderengine::ShadowSettings& shadow,
@@ -1647,11 +1621,6 @@
fillBufferWithoutPremultiplyAlpha();
}
-TEST_P(RenderEngineTest, drawLayers_clearRegion) {
- initializeRenderEngine();
- clearRegion();
-}
-
TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
initializeRenderEngine();
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index b9dabc1..8e666d5 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -361,14 +361,14 @@
return mRenderEngine->supportsBackgroundBlur();
}
-void RenderEngineThreaded::onPrimaryDisplaySizeChanged(ui::Size size) {
+void RenderEngineThreaded::onActiveDisplaySizeChanged(ui::Size size) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::onPrimaryDisplaySizeChanged");
- instance.onPrimaryDisplaySizeChanged(size);
+ ATRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
+ instance.onActiveDisplaySizeChanged(size);
});
}
mCondition.notify_one();
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index f2f5c0f..b197df7 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -65,7 +65,7 @@
void cleanFramebufferCache() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override;
- void onPrimaryDisplaySizeChanged(ui::Size size) override;
+ void onActiveDisplaySizeChanged(ui::Size size) override;
protected:
void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 74d17ce..5a118ec 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -137,7 +137,6 @@
"HdrCapabilities.cpp",
"PixelFormat.cpp",
"PublicFormat.cpp",
- "Size.cpp",
"StaticDisplayInfo.cpp",
],
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index f196ab9..9120972 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -38,12 +38,22 @@
uint64_t value;
+ // For deserialization.
+ static constexpr std::optional<DisplayId> fromValue(uint64_t);
+
+ // As above, but also upcast to Id.
+ template <typename Id>
+ static constexpr std::optional<Id> fromValue(uint64_t value) {
+ if (const auto id = Id::tryCast(DisplayId(value))) {
+ return id;
+ }
+ return {};
+ }
+
protected:
explicit constexpr DisplayId(uint64_t id) : value(id) {}
};
-static_assert(sizeof(DisplayId) == sizeof(uint64_t));
-
inline bool operator==(DisplayId lhs, DisplayId rhs) {
return lhs.value == rhs.value;
}
@@ -80,11 +90,8 @@
// TODO(b/162612135) Remove default constructor
PhysicalDisplayId() = default;
- // TODO(b/162612135) Remove constructor
- explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
-
constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }
private:
@@ -96,10 +103,9 @@
explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
};
-static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
-
struct VirtualDisplayId : DisplayId {
using BaseId = uint32_t;
+
// Flag indicating that this virtual display is backed by the GPU.
static constexpr uint64_t FLAG_GPU = 1ULL << 61;
@@ -163,10 +169,23 @@
explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
};
+constexpr std::optional<DisplayId> DisplayId::fromValue(uint64_t value) {
+ if (const auto id = fromValue<PhysicalDisplayId>(value)) {
+ return id;
+ }
+ if (const auto id = fromValue<VirtualDisplayId>(value)) {
+ return id;
+ }
+ return {};
+}
+
+static_assert(sizeof(DisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
+
+static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
-static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
} // namespace android
diff --git a/libs/ui/include/ui/Size.h b/libs/ui/include/ui/Size.h
index f1e8252..ecc192d 100644
--- a/libs/ui/include/ui/Size.h
+++ b/libs/ui/include/ui/Size.h
@@ -23,103 +23,70 @@
#include <type_traits>
#include <utility>
-namespace android {
-namespace ui {
+namespace android::ui {
-// Forward declare a few things.
-struct Size;
-bool operator==(const Size& lhs, const Size& rhs);
-
-/**
- * A simple value type representing a two-dimensional size
- */
+// A simple value type representing a two-dimensional size.
struct Size {
- int32_t width;
- int32_t height;
+ int32_t width = -1;
+ int32_t height = -1;
- // Special values
- static const Size INVALID;
- static const Size EMPTY;
+ constexpr Size() = default;
- // ------------------------------------------------------------------------
- // Construction
- // ------------------------------------------------------------------------
-
- Size() : Size(INVALID) {}
template <typename T>
- Size(T&& w, T&& h)
- : width(Size::clamp<int32_t, T>(std::forward<T>(w))),
- height(Size::clamp<int32_t, T>(std::forward<T>(h))) {}
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
+ constexpr Size(T w, T h) : width(clamp<int32_t>(w)), height(clamp<int32_t>(h)) {}
int32_t getWidth() const { return width; }
int32_t getHeight() const { return height; }
- template <typename T>
- void setWidth(T&& v) {
- width = Size::clamp<int32_t, T>(std::forward<T>(v));
- }
- template <typename T>
- void setHeight(T&& v) {
- height = Size::clamp<int32_t, T>(std::forward<T>(v));
- }
-
- // ------------------------------------------------------------------------
- // Assignment
- // ------------------------------------------------------------------------
-
- void set(const Size& size) { *this = size; }
- template <typename T>
- void set(T&& w, T&& h) {
- set(Size(std::forward<T>(w), std::forward<T>(h)));
- }
-
- // Sets the value to INVALID
- void makeInvalid() { set(INVALID); }
-
- // Sets the value to EMPTY
- void clear() { set(EMPTY); }
-
- // ------------------------------------------------------------------------
- // Semantic checks
- // ------------------------------------------------------------------------
-
// Valid means non-negative width and height
bool isValid() const { return width >= 0 && height >= 0; }
// Empty means zero width and height
- bool isEmpty() const { return *this == EMPTY; }
+ bool isEmpty() const;
- // ------------------------------------------------------------------------
- // Clamp Helpers
- // ------------------------------------------------------------------------
-
- // Note: We use only features available in C++11 here for compatibility with
- // external targets which include this file directly or indirectly and which
- // themselves use C++11.
-
- // C++11 compatible replacement for std::remove_cv_reference_t [C++20]
template <typename T>
- using remove_cv_reference_t =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ void setWidth(T v) {
+ width = clamp<int32_t>(v);
+ }
+
+ template <typename T>
+ void setHeight(T v) {
+ height = clamp<int32_t>(v);
+ }
+
+ void set(Size size) { *this = size; }
+
+ template <typename T>
+ void set(T w, T h) {
+ set(Size(w, h));
+ }
+
+ // Sets the value to kInvalidSize
+ void makeInvalid();
+
+ // Sets the value to kEmptySize
+ void clear();
+
+ // TODO: Replace with std::remove_cvref_t in C++20.
+ template <typename T>
+ using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
// Takes a value of type FromType, and ensures it can be represented as a value of type ToType,
// clamping the input value to the output range if necessary.
template <typename ToType, typename FromType>
- static Size::remove_cv_reference_t<ToType>
- clamp(typename std::enable_if<
- std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_specialized &&
- std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_specialized,
- FromType>::type v) {
- using BareToType = remove_cv_reference_t<ToType>;
- using BareFromType = remove_cv_reference_t<FromType>;
- static constexpr auto toHighest = std::numeric_limits<BareToType>::max();
- static constexpr auto toLowest = std::numeric_limits<BareToType>::lowest();
- static constexpr auto fromHighest = std::numeric_limits<BareFromType>::max();
- static constexpr auto fromLowest = std::numeric_limits<BareFromType>::lowest();
+ static constexpr remove_cvref_t<ToType> clamp(FromType v) {
+ using BareToType = remove_cvref_t<ToType>;
+ using ToLimits = std::numeric_limits<BareToType>;
+
+ using BareFromType = remove_cvref_t<FromType>;
+ using FromLimits = std::numeric_limits<BareFromType>;
+
+ static_assert(ToLimits::is_specialized && FromLimits::is_specialized);
+
+ constexpr auto toHighest = ToLimits::max();
+ constexpr auto toLowest = ToLimits::lowest();
+ constexpr auto fromHighest = FromLimits::max();
+ constexpr auto fromLowest = FromLimits::lowest();
// Get the closest representation of [toLowest, toHighest] in type
// FromType to use to clamp the input value before conversion.
@@ -127,37 +94,35 @@
// std::common_type<...> is used to get a value-preserving type for the
// top end of the range.
using CommonHighestType = std::common_type_t<BareToType, BareFromType>;
+ using CommonLimits = std::numeric_limits<CommonHighestType>;
// std::make_signed<std::common_type<...>> is used to get a
// value-preserving type for the bottom end of the range, except this is
// a bit trickier for non-integer types like float.
- using CommonLowestType =
- std::conditional_t<std::numeric_limits<CommonHighestType>::is_integer,
- std::make_signed_t<std::conditional_t<
- std::numeric_limits<CommonHighestType>::is_integer,
- CommonHighestType, int /* not used */>>,
- CommonHighestType>;
+ using CommonLowestType = std::conditional_t<
+ CommonLimits::is_integer,
+ std::make_signed_t<std::conditional_t<CommonLimits::is_integer, CommonHighestType,
+ int /* not used */>>,
+ CommonHighestType>;
// We can then compute the clamp range in a way that can be later
// trivially converted to either the 'from' or 'to' types, and be
- // representabile in either.
- static constexpr auto commonClampHighest =
- std::min(static_cast<CommonHighestType>(fromHighest),
- static_cast<CommonHighestType>(toHighest));
- static constexpr auto commonClampLowest =
- std::max(static_cast<CommonLowestType>(fromLowest),
- static_cast<CommonLowestType>(toLowest));
+ // representable in either.
+ constexpr auto commonClampHighest = std::min(static_cast<CommonHighestType>(fromHighest),
+ static_cast<CommonHighestType>(toHighest));
+ constexpr auto commonClampLowest = std::max(static_cast<CommonLowestType>(fromLowest),
+ static_cast<CommonLowestType>(toLowest));
- static constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
- static constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);
+ constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
+ constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);
// A clamp is needed only if the range we are clamping to is not the
// same as the range of the input.
- static constexpr bool isClampNeeded =
+ constexpr bool isClampNeeded =
(fromLowest != fromClampLowest) || (fromHighest != fromClampHighest);
// If a clamp is not needed, the conversion is just a trivial cast.
- if (!isClampNeeded) {
+ if constexpr (!isClampNeeded) {
return static_cast<BareToType>(v);
}
@@ -170,34 +135,46 @@
// Otherwise clamping is done by using the already computed endpoints
// for each type.
- return (v <= fromClampLowest)
- ? toClampLowest
- : ((v >= fromClampHighest) ? toClampHighest : static_cast<BareToType>(v));
+ if (v <= fromClampLowest) {
+ return toClampLowest;
+ }
+
+ return v >= fromClampHighest ? toClampHighest : static_cast<BareToType>(v);
}
};
-// ------------------------------------------------------------------------
-// Comparisons
-// ------------------------------------------------------------------------
+constexpr Size kInvalidSize;
+constexpr Size kEmptySize{0, 0};
-inline bool operator==(const Size& lhs, const Size& rhs) {
+inline void Size::makeInvalid() {
+ set(kInvalidSize);
+}
+
+inline void Size::clear() {
+ set(kEmptySize);
+}
+
+inline bool operator==(Size lhs, Size rhs) {
return lhs.width == rhs.width && lhs.height == rhs.height;
}
-inline bool operator!=(const Size& lhs, const Size& rhs) {
- return !operator==(lhs, rhs);
+inline bool Size::isEmpty() const {
+ return *this == kEmptySize;
}
-inline bool operator<(const Size& lhs, const Size& rhs) {
+inline bool operator!=(Size lhs, Size rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator<(Size lhs, Size rhs) {
// Orders by increasing width, then height.
if (lhs.width != rhs.width) return lhs.width < rhs.width;
return lhs.height < rhs.height;
}
// Defining PrintTo helps with Google Tests.
-static inline void PrintTo(const Size& size, ::std::ostream* os) {
- *os << "Size(" << size.width << ", " << size.height << ")";
+inline void PrintTo(Size size, std::ostream* stream) {
+ *stream << "Size(" << size.width << ", " << size.height << ')';
}
-} // namespace ui
-} // namespace android
+} // namespace android::ui
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
index 1d908b8..8ddee7e 100644
--- a/libs/ui/tests/DisplayId_test.cpp
+++ b/libs/ui/tests/DisplayId_test.cpp
@@ -32,6 +32,9 @@
EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+ EXPECT_EQ(id, DisplayId::fromValue(id.value));
+ EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
}
TEST(DisplayIdTest, createPhysicalIdFromPort) {
@@ -43,6 +46,9 @@
EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+ EXPECT_EQ(id, DisplayId::fromValue(id.value));
+ EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
}
TEST(DisplayIdTest, createGpuVirtualId) {
@@ -52,6 +58,9 @@
EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
EXPECT_FALSE(HalDisplayId::tryCast(id));
+
+ EXPECT_EQ(id, DisplayId::fromValue(id.value));
+ EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value));
}
TEST(DisplayIdTest, createHalVirtualId) {
@@ -61,6 +70,9 @@
EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+ EXPECT_EQ(id, DisplayId::fromValue(id.value));
+ EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value));
}
} // namespace android::ui
diff --git a/libs/ui/tests/Size_test.cpp b/libs/ui/tests/Size_test.cpp
index 5f75aea..acef47f 100644
--- a/libs/ui/tests/Size_test.cpp
+++ b/libs/ui/tests/Size_test.cpp
@@ -93,9 +93,8 @@
}
{
- const auto& s = Size::INVALID;
- EXPECT_FALSE(s.isValid());
- EXPECT_FALSE(s.isEmpty());
+ EXPECT_FALSE(kInvalidSize.isValid());
+ EXPECT_FALSE(kInvalidSize.isEmpty());
}
{
@@ -112,9 +111,8 @@
}
{
- const auto& s = Size::EMPTY;
- EXPECT_TRUE(s.isValid());
- EXPECT_TRUE(s.isEmpty());
+ EXPECT_TRUE(kEmptySize.isValid());
+ EXPECT_TRUE(kEmptySize.isEmpty());
}
{
diff --git a/libs/vibrator/ExternalVibrationUtils.cpp b/libs/vibrator/ExternalVibrationUtils.cpp
index 749c568..980b08b 100644
--- a/libs/vibrator/ExternalVibrationUtils.cpp
+++ b/libs/vibrator/ExternalVibrationUtils.cpp
@@ -56,6 +56,36 @@
}
}
+void applyHapticScale(float* buffer, size_t length, HapticScale scale) {
+ if (scale == HapticScale::MUTE) {
+ memset(buffer, 0, length * sizeof(float));
+ return;
+ }
+ if (scale == HapticScale::NONE) {
+ return;
+ }
+ float gamma = getHapticScaleGamma(scale);
+ float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(scale);
+ for (size_t i = 0; i < length; i++) {
+ float sign = buffer[i] >= 0 ? 1.0 : -1.0;
+ buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
+ * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
+ }
+}
+
+void clipHapticData(float* buffer, size_t length, float limit) {
+ if (isnan(limit) || limit == 0) {
+ return;
+ }
+ limit = fabsf(limit);
+ for (size_t i = 0; i < length; i++) {
+ float sign = buffer[i] >= 0 ? 1.0 : -1.0;
+ if (fabsf(buffer[i]) > limit) {
+ buffer[i] = limit * sign;
+ }
+ }
+}
+
} // namespace
bool isValidHapticScale(HapticScale scale) {
@@ -71,21 +101,11 @@
return false;
}
-void scaleHapticData(float* buffer, size_t length, HapticScale scale) {
- if (!isValidHapticScale(scale) || scale == HapticScale::NONE) {
- return;
+void scaleHapticData(float* buffer, size_t length, HapticScale scale, float limit) {
+ if (isValidHapticScale(scale)) {
+ applyHapticScale(buffer, length, scale);
}
- if (scale == HapticScale::MUTE) {
- memset(buffer, 0, length * sizeof(float));
- return;
- }
- float gamma = getHapticScaleGamma(scale);
- float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(scale);
- for (size_t i = 0; i < length; i++) {
- float sign = buffer[i] >= 0 ? 1.0 : -1.0;
- buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
- * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
- }
+ clipHapticData(buffer, length, limit);
}
} // namespace android::os
diff --git a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
index 20045d0..84357fc 100644
--- a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
+++ b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
@@ -32,7 +32,11 @@
bool isValidHapticScale(HapticScale scale);
-void scaleHapticData(float* buffer, size_t length, HapticScale scale);
+/* Scales the haptic data in given buffer using the selected HapticScale and ensuring no absolute
+ * value will be larger than the absolute of given limit.
+ * The limit will be ignored if it is NaN or zero.
+ */
+void scaleHapticData(float* buffer, size_t length, HapticScale scale, float limit);
} // namespace android::os
diff --git a/services/automotive/display/AutomotiveDisplayProxyService.cpp b/services/automotive/display/AutomotiveDisplayProxyService.cpp
index d6fc695..d205231 100644
--- a/services/automotive/display/AutomotiveDisplayProxyService.cpp
+++ b/services/automotive/display/AutomotiveDisplayProxyService.cpp
@@ -34,7 +34,10 @@
sp<IBinder> displayToken = nullptr;
sp<SurfaceControl> surfaceControl = nullptr;
if (it == mDisplays.end()) {
- displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
+ if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
+ displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+ }
+
if (displayToken == nullptr) {
ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
return nullptr;
@@ -157,7 +160,11 @@
HwDisplayConfig activeConfig;
HwDisplayState activeState;
- auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
+ sp<IBinder> displayToken;
+ if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
+ displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+ }
+
if (displayToken == nullptr) {
ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
} else {
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 6612a93..24d186c 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -73,6 +73,7 @@
"libui",
"lib-platform-compat-native-api",
"server_configurable_flags",
+ "InputFlingerProperties",
],
static_libs: [
"libattestation",
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index a50e5c7..e81dcfe 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -31,6 +31,10 @@
namespace android {
+using gui::FocusRequest;
+using gui::WindowInfo;
+using gui::WindowInfoHandle;
+
static int32_t exceptionCodeFromStatusT(status_t status) {
switch (status) {
case OK:
@@ -110,9 +114,9 @@
return mDispatcher;
}
-class BinderWindowHandle : public InputWindowHandle {
+class BinderWindowHandle : public WindowInfoHandle {
public:
- BinderWindowHandle(const InputWindowInfo& info) { mInfo = info; }
+ BinderWindowHandle(const WindowInfo& info) { mInfo = info; }
bool updateInfo() override {
return true;
@@ -120,13 +124,13 @@
};
binder::Status InputManager::setInputWindows(
- const std::vector<InputWindowInfo>& infos,
+ const std::vector<WindowInfo>& infos,
const sp<ISetInputWindowsListener>& setInputWindowsListener) {
- std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay;
+ std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
- std::vector<sp<InputWindowHandle>> handles;
+ std::vector<sp<WindowInfoHandle>> handles;
for (const auto& info : infos) {
- handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
+ handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
}
mDispatcher->setInputWindows(handlesPerDisplay);
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 49bea13..035a9a3 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -105,12 +105,12 @@
status_t dump(int fd, const Vector<String16>& args) override;
binder::Status setInputWindows(
- const std::vector<InputWindowInfo>& handles,
+ const std::vector<gui::WindowInfo>& handles,
const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
- binder::Status setFocusedWindow(const FocusRequest&) override;
+ binder::Status setFocusedWindow(const gui::FocusRequest&) override;
private:
sp<InputReaderInterface> mReader;
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
index 9cc777d..f26a9a9 100644
--- a/services/inputflinger/InputReaderBase.cpp
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -19,9 +19,9 @@
//#define LOG_NDEBUG 0
#include "InputReaderBase.h"
+#include <ftl/NamedEnum.h>
#include "input/DisplayViewport.h"
#include "input/Input.h"
-#include "input/NamedEnum.h"
#include <android/log.h>
#include <android-base/stringprintf.h>
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index bc77b8a..f77c029 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -18,8 +18,11 @@
#include <android/os/IInputConstants.h>
#include <binder/Binder.h>
+#include <gui/constants.h>
#include "../dispatcher/InputDispatcher.h"
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
using android::os::IInputConstants;
using android::os::InputEventInjectionResult;
using android::os::InputEventInjectionSync;
@@ -173,7 +176,7 @@
PreallocatedInputEventFactory mEventFactory;
};
-class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
+class FakeWindowHandle : public WindowInfoHandle, public FakeInputReceiver {
public:
static const int32_t WIDTH = 200;
static const int32_t HEIGHT = 200;
@@ -188,7 +191,7 @@
virtual bool updateInfo() override {
mInfo.token = mClientChannel->getConnectionToken();
mInfo.name = "FakeWindowHandle";
- mInfo.type = InputWindowInfo::Type::APPLICATION;
+ mInfo.type = WindowInfo::Type::APPLICATION;
mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
mInfo.frameLeft = mFrame.left;
mInfo.frameTop = mFrame.top;
@@ -234,8 +237,8 @@
/* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
identityTransform, /* xPrecision */ 0,
/* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, currentTime, currentTime,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, currentTime, currentTime,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
return event;
}
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index 1b3888b..7c7a16b 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -67,6 +67,7 @@
"libutils",
"lib-platform-compat-native-api",
"server_configurable_flags",
+ "InputFlingerProperties",
],
static_libs: [
"libattestation",
diff --git a/services/inputflinger/dispatcher/DragState.cpp b/services/inputflinger/dispatcher/DragState.cpp
index 2e2df43..e1844a4 100644
--- a/services/inputflinger/dispatcher/DragState.cpp
+++ b/services/inputflinger/dispatcher/DragState.cpp
@@ -16,9 +16,7 @@
#include "DragState.h"
#include <android-base/stringprintf.h>
-#include <input/InputWindow.h>
-using android::InputWindowHandle;
using android::base::StringPrintf;
namespace android::inputdispatcher {
diff --git a/services/inputflinger/dispatcher/DragState.h b/services/inputflinger/dispatcher/DragState.h
index 06453d8..b3c5709 100644
--- a/services/inputflinger/dispatcher/DragState.h
+++ b/services/inputflinger/dispatcher/DragState.h
@@ -17,22 +17,22 @@
#ifndef _UI_INPUT_INPUTDISPATCHER_DRAGSTATE_H
#define _UI_INPUT_INPUTDISPATCHER_DRAGSTATE_H
+#include <gui/WindowInfo.h>
#include <utils/RefBase.h>
#include <string>
namespace android {
-class InputWindowHandle;
-
namespace inputdispatcher {
+
struct DragState {
- DragState(const sp<android::InputWindowHandle>& windowHandle) : dragWindow(windowHandle) {}
+ DragState(const sp<android::gui::WindowInfoHandle>& windowHandle) : dragWindow(windowHandle) {}
void dump(std::string& dump, const char* prefix = "");
// The window being dragged.
- const sp<InputWindowHandle> dragWindow;
+ const sp<android::gui::WindowInfoHandle> dragWindow;
// The last drag hover window which could receive the drag event.
- sp<InputWindowHandle> dragHoverWindowHandle;
+ sp<android::gui::WindowInfoHandle> dragHoverWindowHandle;
// Indicates the if received first event to check for button state.
bool isStartDrag = false;
// Indicate if the stylus button is down at the start of the drag.
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 881024f..8f4527d 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -176,10 +176,11 @@
}
return StringPrintf("KeyEvent(deviceId=%d, eventTime=%" PRIu64
", source=0x%08x, displayId=%" PRId32 ", action=%s, "
- "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
+ "flags=0x%08x, keyCode=%s(%d), scanCode=%d, metaState=0x%08x, "
"repeatCount=%d), policyFlags=0x%08x",
deviceId, eventTime, source, displayId, KeyEvent::actionToString(action),
- flags, keyCode, scanCode, metaState, repeatCount, policyFlags);
+ flags, KeyEvent::getLabel(keyCode), keyCode, scanCode, metaState,
+ repeatCount, policyFlags);
}
void KeyEntry::recycle() {
@@ -296,12 +297,14 @@
volatile int32_t DispatchEntry::sNextSeqAtomic;
DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
- ui::Transform transform, float globalScaleFactor, int2 displaySize)
+ ui::Transform transform, float globalScaleFactor,
+ uint32_t displayOrientation, int2 displaySize)
: seq(nextSeq()),
eventEntry(std::move(eventEntry)),
targetFlags(targetFlags),
transform(transform),
globalScaleFactor(globalScaleFactor),
+ displayOrientation(displayOrientation),
displaySize(displaySize),
deliveryTime(0),
resolvedAction(0),
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index ebbd8e9..1b7fcf2 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -20,8 +20,8 @@
#include "InjectionState.h"
#include "InputTarget.h"
+#include <gui/InputApplication.h>
#include <input/Input.h>
-#include <input/InputApplication.h>
#include <stdint.h>
#include <utils/Timers.h>
#include <functional>
@@ -215,6 +215,7 @@
int32_t targetFlags;
ui::Transform transform;
float globalScaleFactor;
+ uint32_t displayOrientation;
int2 displaySize;
// Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
// and will be undefined before that.
@@ -228,7 +229,8 @@
int32_t resolvedFlags;
DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
- ui::Transform transform, float globalScaleFactor, int2 displaySize);
+ ui::Transform transform, float globalScaleFactor, uint32_t displayOrientation,
+ int2 displaySize);
inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
diff --git a/services/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index fb19435..4a75773 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -27,12 +27,15 @@
#include <android-base/stringprintf.h>
#include <binder/Binder.h>
-#include <input/InputWindow.h>
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
+#include <gui/WindowInfo.h>
#include <log/log.h>
#include "FocusResolver.h"
+using android::gui::FocusRequest;
+using android::gui::WindowInfoHandle;
+
namespace android::inputdispatcher {
sp<IBinder> FocusResolver::getFocusedWindowToken(int32_t displayId) const {
@@ -52,7 +55,7 @@
* we will check if the previous focus request is eligible to receive focus.
*/
std::optional<FocusResolver::FocusChanges> FocusResolver::setInputWindows(
- int32_t displayId, const std::vector<sp<InputWindowHandle>>& windows) {
+ int32_t displayId, const std::vector<sp<WindowInfoHandle>>& windows) {
std::string removeFocusReason;
// Check if the currently focused window is still focusable.
@@ -87,7 +90,7 @@
}
std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow(
- const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows) {
+ const FocusRequest& request, const std::vector<sp<WindowInfoHandle>>& windows) {
const int32_t displayId = request.displayId;
const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
if (currentFocus == request.token) {
@@ -136,11 +139,11 @@
}
FocusResolver::Focusability FocusResolver::isTokenFocusable(
- const sp<IBinder>& token, const std::vector<sp<InputWindowHandle>>& windows) {
+ const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows) {
bool allWindowsAreFocusable = true;
bool visibleWindowFound = false;
bool windowFound = false;
- for (const sp<InputWindowHandle>& window : windows) {
+ for (const sp<WindowInfoHandle>& window : windows) {
if (window->getToken() != token) {
continue;
}
diff --git a/services/inputflinger/dispatcher/FocusResolver.h b/services/inputflinger/dispatcher/FocusResolver.h
index afe16b3..1d6cd9a 100644
--- a/services/inputflinger/dispatcher/FocusResolver.h
+++ b/services/inputflinger/dispatcher/FocusResolver.h
@@ -20,9 +20,9 @@
#include <optional>
#include <unordered_map>
-#include <android/FocusRequest.h>
+#include <android/gui/FocusRequest.h>
#include <binder/Binder.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
namespace android::inputdispatcher {
@@ -58,9 +58,10 @@
std::string reason;
};
std::optional<FocusResolver::FocusChanges> setInputWindows(
- int32_t displayId, const std::vector<sp<InputWindowHandle>>& windows);
+ int32_t displayId, const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
std::optional<FocusResolver::FocusChanges> setFocusedWindow(
- const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows);
+ const android::gui::FocusRequest& request,
+ const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
// Display has been removed from the system, clean up old references.
void displayRemoved(int32_t displayId);
@@ -87,8 +88,9 @@
// we expect the focusability of the windows to match since its hard to reason why one window
// can receive focus events and the other cannot when both are backed by the same input channel.
//
- static Focusability isTokenFocusable(const sp<IBinder>& token,
- const std::vector<sp<InputWindowHandle>>& windows);
+ static Focusability isTokenFocusable(
+ const sp<IBinder>& token,
+ const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
// Focus tracking for keys, trackball, etc. A window token can be associated with one or
// more InputWindowHandles. If a window is mirrored, the window and its mirror will share
@@ -99,7 +101,7 @@
// This map will store the focus request per display. When the input window handles are updated,
// the current request will be checked to see if it can be processed at that time.
- std::unordered_map<int32_t /* displayId */, FocusRequest> mFocusRequestByDisplay;
+ std::unordered_map<int32_t /* displayId */, android::gui::FocusRequest> mFocusRequestByDisplay;
// Last reason for not granting a focus request. This is used to add more debug information
// in the event logs.
@@ -108,7 +110,7 @@
std::optional<FocusResolver::FocusChanges> updateFocusedWindow(
int32_t displayId, const std::string& reason, const sp<IBinder>& token,
const std::string& tokenName = "");
- std::optional<FocusRequest> getFocusRequest(int32_t displayId);
+ std::optional<android::gui::FocusRequest> getFocusRequest(int32_t displayId);
};
} // namespace android::inputdispatcher
\ No newline at end of file
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 1899c5f..07b4f30 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -47,6 +47,7 @@
// Log debug messages about hover events.
#define DEBUG_HOVER 0
+#include <InputFlingerProperties.sysprop.h>
#include <android-base/chrono_utils.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
@@ -55,7 +56,6 @@
#include <binder/IServiceManager.h>
#include <com/android/internal/compat/IPlatformCompatNative.h>
#include <input/InputDevice.h>
-#include <input/InputWindow.h>
#include <log/log.h>
#include <log/log_event_list.h>
#include <powermanager/PowerManager.h>
@@ -81,6 +81,10 @@
using android::base::HwTimeoutMultiplier;
using android::base::Result;
using android::base::StringPrintf;
+using android::gui::FocusRequest;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
using android::os::BlockUntrustedTouchesMode;
using android::os::IInputConstants;
using android::os::InputEventInjectionResult;
@@ -93,7 +97,8 @@
// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
static bool isPerWindowInputRotationEnabled() {
static const bool PER_WINDOW_INPUT_ROTATION =
- base::GetBoolProperty("persist.debug.per_window_input_rotation", false);
+ sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
+
return PER_WINDOW_INPUT_ROTATION;
}
@@ -290,7 +295,7 @@
return it != map.end() ? it->second : V{};
}
-static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
+static bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
if (first == second) {
return true;
}
@@ -302,7 +307,7 @@
return first->getToken() == second->getToken();
}
-static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
+static bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
if (first == nullptr || second == nullptr) {
return false;
}
@@ -319,13 +324,14 @@
int32_t inputTargetFlags) {
if (eventEntry->type == EventEntry::Type::MOTION) {
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
- if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) == 0) {
+ if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
+ (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
const ui::Transform identityTransform;
- // Use identity transform for events that are not pointer events because their axes
- // values do not represent on-screen coordinates, so they should not have any window
- // transformations applied to them.
+ // Use identity transform for joystick and position-based (touchpad) events because they
+ // don't depend on the window transform.
return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
1.0f /*globalScaleFactor*/,
+ inputTarget.displayOrientation,
inputTarget.displaySize);
}
}
@@ -334,6 +340,7 @@
const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
inputTarget.globalScaleFactor,
+ inputTarget.displayOrientation,
inputTarget.displaySize);
}
@@ -386,6 +393,7 @@
std::unique_ptr<DispatchEntry> dispatchEntry =
std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
firstPointerTransform, inputTarget.globalScaleFactor,
+ inputTarget.displayOrientation,
inputTarget.displaySize);
return dispatchEntry;
}
@@ -624,7 +632,7 @@
return; // The focused application has changed.
}
- const sp<InputWindowHandle>& focusedWindowHandle =
+ const sp<WindowInfoHandle>& focusedWindowHandle =
getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
if (focusedWindowHandle != nullptr) {
return; // We now have a focused window. No need for ANR.
@@ -673,7 +681,7 @@
}
std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
- sp<InputWindowHandle> window = getWindowHandleLocked(token);
+ sp<WindowInfoHandle> window = getWindowHandleLocked(token);
if (window != nullptr) {
return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
}
@@ -885,7 +893,7 @@
motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
int32_t y = static_cast<int32_t>(
motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> touchedWindowHandle =
+ sp<WindowInfoHandle> touchedWindowHandle =
findTouchedWindowAtLocked(displayId, x, y, nullptr);
if (touchedWindowHandle != nullptr &&
touchedWindowHandle->getApplicationToken() !=
@@ -898,8 +906,7 @@
}
// Alternatively, maybe there's a gesture monitor that could handle this event
- std::vector<TouchedMonitor> gestureMonitors =
- findTouchedGestureMonitorsLocked(displayId, {});
+ std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
for (TouchedMonitor& gestureMonitor : gestureMonitors) {
sp<Connection> connection =
getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
@@ -990,46 +997,34 @@
}
}
-sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
- int32_t y, TouchState* touchState,
- bool addOutsideTargets,
- bool addPortalWindows,
- bool ignoreDragWindow) {
- if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
- LOG_ALWAYS_FATAL(
- "Must provide a valid touch state if adding portal windows or outside targets");
+sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
+ int32_t y, TouchState* touchState,
+ bool addOutsideTargets,
+ bool ignoreDragWindow) {
+ if (addOutsideTargets && touchState == nullptr) {
+ LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
}
// Traverse windows from front to back to find touched window.
- const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
- for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
continue;
}
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const WindowInfo* windowInfo = windowHandle->getInfo();
if (windowInfo->displayId == displayId) {
auto flags = windowInfo->flags;
if (windowInfo->visible) {
- if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
- bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
- !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
+ bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
+ !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
- int32_t portalToDisplayId = windowInfo->portalToDisplayId;
- if (portalToDisplayId != ADISPLAY_ID_NONE &&
- portalToDisplayId != displayId) {
- if (addPortalWindows) {
- // For the monitoring channels of the display.
- touchState->addPortalWindow(windowHandle);
- }
- return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
- addOutsideTargets, addPortalWindows);
- }
// Found window.
return windowHandle;
}
}
- if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
+ if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
touchState->addOrUpdateWindow(windowHandle,
InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
BitSet32(0));
@@ -1041,17 +1036,11 @@
}
std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
- int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
+ int32_t displayId) const {
std::vector<TouchedMonitor> touchedMonitors;
std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
addGestureMonitors(monitors, touchedMonitors);
- for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
- const InputWindowInfo* windowInfo = portalWindow->getInfo();
- monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
- addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
- -windowInfo->frameTop);
- }
return touchedMonitors;
}
@@ -1256,6 +1245,11 @@
entry.deviceId);
#endif
+ // Reset key repeating in case a keyboard device was disabled or enabled.
+ if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
+ resetKeyRepeatLocked();
+ }
+
CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
options.deviceId = entry.deviceId;
synthesizeCancelationEventsForAllConnectionsLocked(options);
@@ -1582,23 +1576,6 @@
// Add monitor channels from event's or focused display.
addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
- if (isPointerEvent) {
- std::unordered_map<int32_t, TouchState>::iterator it =
- mTouchStatesByDisplay.find(entry->displayId);
- if (it != mTouchStatesByDisplay.end()) {
- const TouchState& state = it->second;
- if (!state.portalWindows.empty()) {
- // The event has gone through these portal windows, so we add monitoring targets of
- // the corresponding displays as well.
- for (size_t i = 0; i < state.portalWindows.size(); i++) {
- const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
- addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
- -windowInfo->frameLeft, -windowInfo->frameTop);
- }
- }
- }
- }
-
// Dispatch the motion.
if (conflictingPointerActions) {
CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
@@ -1609,7 +1586,7 @@
return true;
}
-void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
+void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
bool isExiting, const MotionEntry& motionEntry) {
// If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
// be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
@@ -1789,7 +1766,7 @@
std::string reason;
int32_t displayId = getTargetDisplayId(entry);
- sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
+ sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
@@ -1916,8 +1893,8 @@
// Update the touch state as needed based on the properties of the touch event.
InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
- sp<InputWindowHandle> newTouchedWindowHandle;
+ sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
+ sp<WindowInfoHandle> newTouchedWindowHandle;
// Copy current touch state into tempTouchState.
// This state will be used to update mTouchStatesByDisplay at the end of this function.
@@ -1986,12 +1963,11 @@
y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
}
bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
- newTouchedWindowHandle =
- findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
- isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
+ newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
+ isDown /*addOutsideTargets*/);
std::vector<TouchedMonitor> newGestureMonitors = isDown
- ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
+ ? findTouchedGestureMonitorsLocked(displayId)
: std::vector<TouchedMonitor>{};
// Figure out whether splitting will be allowed for this window.
@@ -2110,7 +2086,7 @@
int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> oldTouchedWindowHandle =
+ sp<WindowInfoHandle> oldTouchedWindowHandle =
tempTouchState.getFirstForegroundWindowHandle();
newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
if (oldTouchedWindowHandle != newTouchedWindowHandle &&
@@ -2209,15 +2185,15 @@
// Check whether windows listening for outside touches are owned by the same UID. If it is
// set the policy flag that we will not reveal coordinate information to this window.
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- sp<InputWindowHandle> foregroundWindowHandle =
+ sp<WindowInfoHandle> foregroundWindowHandle =
tempTouchState.getFirstForegroundWindowHandle();
if (foregroundWindowHandle) {
const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
- sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
- if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
- tempTouchState.addOrUpdateWindow(inputWindowHandle,
+ sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
+ if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
+ tempTouchState.addOrUpdateWindow(windowInfoHandle,
InputTarget::FLAG_ZERO_COORDS,
BitSet32(0));
}
@@ -2233,15 +2209,15 @@
// engine only supports touch events. We would need to add a mechanism similar
// to View.onGenericMotionEvent to enable wallpapers to handle these events.
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- sp<InputWindowHandle> foregroundWindowHandle =
+ sp<WindowInfoHandle> foregroundWindowHandle =
tempTouchState.getFirstForegroundWindowHandle();
if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
- const std::vector<sp<InputWindowHandle>>& windowHandles =
+ const std::vector<sp<WindowInfoHandle>>& windowHandles =
getWindowHandlesLocked(displayId);
- for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
- const InputWindowInfo* info = windowHandle->getInfo();
+ for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
+ const WindowInfo* info = windowHandle->getInfo();
if (info->displayId == displayId &&
- windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
+ windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
tempTouchState
.addOrUpdateWindow(windowHandle,
InputTarget::FLAG_WINDOW_IS_OBSCURED |
@@ -2360,10 +2336,9 @@
}
void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
- const sp<InputWindowHandle> dropWindow =
+ const sp<WindowInfoHandle> dropWindow =
findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
- false /*addOutsideTargets*/, false /*addPortalWindows*/,
- true /*ignoreDragWindow*/);
+ false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
if (dropWindow) {
vec2 local = dropWindow->getInfo()->transform.transform(x, y);
notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y);
@@ -2395,10 +2370,9 @@
return;
}
- const sp<InputWindowHandle> hoverWindowHandle =
+ const sp<WindowInfoHandle> hoverWindowHandle =
findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
- false /*addOutsideTargets*/, false /*addPortalWindows*/,
- true /*ignoreDragWindow*/);
+ false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
// enqueue drag exit if needed.
if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
!haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
@@ -2420,7 +2394,7 @@
}
}
-void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds,
std::vector<InputTarget>& inputTargets) {
std::vector<InputTarget>::iterator it =
@@ -2430,7 +2404,7 @@
windowHandle->getToken();
});
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const WindowInfo* windowInfo = windowHandle->getInfo();
if (it == inputTargets.end()) {
InputTarget inputTarget;
@@ -2443,6 +2417,7 @@
inputTarget.inputChannel = inputChannel;
inputTarget.flags = targetFlags;
inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
+ inputTarget.displayOrientation = windowInfo->displayOrientation;
inputTarget.displaySize =
int2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
inputTargets.push_back(inputTarget);
@@ -2481,7 +2456,7 @@
inputTargets.push_back(target);
}
-bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
const InjectionState* injectionState) {
if (injectionState &&
(windowHandle == nullptr ||
@@ -2506,8 +2481,8 @@
* another window handle. We only check a few preconditions. Actually
* checking the bounds is left to the caller.
*/
-static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
- const sp<InputWindowHandle>& otherHandle) {
+static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
+ const sp<WindowInfoHandle>& otherHandle) {
// Compare by token so cloned layers aren't counted
if (haveSameToken(windowHandle, otherHandle)) {
return false;
@@ -2516,8 +2491,7 @@
auto otherInfo = otherHandle->getInfo();
if (!otherInfo->visible) {
return false;
- } else if (otherInfo->alpha == 0 &&
- otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
+ } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
// Those act as if they were invisible, so we don't need to flag them.
// We do want to potentially flag touchable windows even if they have 0
// opacity, since they can consume touches and alter the effects of the
@@ -2555,20 +2529,20 @@
* If neither of those is true, then it means the touch can be allowed.
*/
InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
- const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
+ const WindowInfo* windowInfo = windowHandle->getInfo();
int32_t displayId = windowInfo->displayId;
- const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
TouchOcclusionInfo info;
info.hasBlockingOcclusion = false;
info.obscuringOpacity = 0;
info.obscuringUid = -1;
std::map<int32_t, float> opacityByUid;
- for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+ for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
break; // All future windows are below us. Exit early.
}
- const InputWindowInfo* otherInfo = otherHandle->getInfo();
+ const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
!haveSameApplicationToken(windowInfo, otherInfo)) {
if (DEBUG_TOUCH_OCCLUSION) {
@@ -2607,7 +2581,7 @@
return info;
}
-std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
+std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
bool isTouchedWindow) const {
return StringPrintf(INDENT2
"* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
@@ -2641,15 +2615,15 @@
return true;
}
-bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
+bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
int32_t x, int32_t y) const {
int32_t displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
- for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
break; // All future windows are below us. Exit early.
}
- const InputWindowInfo* otherInfo = otherHandle->getInfo();
+ const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
otherInfo->frameContainsPoint(x, y)) {
return true;
@@ -2658,15 +2632,15 @@
return false;
}
-bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
+bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
int32_t displayId = windowHandle->getInfo()->displayId;
- const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
- for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const WindowInfo* windowInfo = windowHandle->getInfo();
+ for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
if (windowHandle == otherHandle) {
break; // All future windows are below us. Exit early.
}
- const InputWindowInfo* otherInfo = otherHandle->getInfo();
+ const WindowInfo* otherInfo = otherHandle->getInfo();
if (canBeObscuredBy(windowHandle, otherHandle) &&
otherInfo->overlaps(windowInfo)) {
return true;
@@ -2676,8 +2650,7 @@
}
std::string InputDispatcher::getApplicationWindowLabel(
- const InputApplicationHandle* applicationHandle,
- const sp<InputWindowHandle>& windowHandle) {
+ const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
if (applicationHandle != nullptr) {
if (windowHandle != nullptr) {
return applicationHandle->getName() + " - " + windowHandle->getName();
@@ -2700,10 +2673,10 @@
return;
}
int32_t displayId = getTargetDisplayId(eventEntry);
- sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
+ sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
if (focusedWindowHandle != nullptr) {
- const InputWindowInfo* info = focusedWindowHandle->getInfo();
- if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
+ const WindowInfo* info = focusedWindowHandle->getInfo();
+ if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
#endif
@@ -3158,6 +3131,7 @@
motionEntry.xPrecision, motionEntry.yPrecision,
motionEntry.xCursorPosition,
motionEntry.yCursorPosition,
+ dispatchEntry->displayOrientation,
dispatchEntry->displaySize.x,
dispatchEntry->displaySize.y,
motionEntry.downTime, motionEntry.eventTime,
@@ -3474,10 +3448,10 @@
#endif
InputTarget target;
- sp<InputWindowHandle> windowHandle =
+ sp<WindowInfoHandle> windowHandle =
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
if (windowHandle != nullptr) {
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const WindowInfo* windowInfo = windowHandle->getInfo();
target.setDefaultPointerTransform(windowInfo->transform);
target.globalScaleFactor = windowInfo->globalScaleFactor;
}
@@ -3541,10 +3515,10 @@
#endif
InputTarget target;
- sp<InputWindowHandle> windowHandle =
+ sp<WindowInfoHandle> windowHandle =
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
if (windowHandle != nullptr) {
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const WindowInfo* windowInfo = windowHandle->getInfo();
target.setDefaultPointerTransform(windowInfo->transform);
target.globalScaleFactor = windowInfo->globalScaleFactor;
}
@@ -3870,8 +3844,8 @@
args->action, args->actionButton, args->flags, args->edgeFlags,
args->metaState, args->buttonState, args->classification, transform,
args->xPrecision, args->yPrecision, args->xCursorPosition,
- args->yCursorPosition, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
+ args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
+ INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
args->pointerCount, args->pointerProperties, args->pointerCoords);
policyFlags |= POLICY_FLAG_FILTERED;
@@ -3894,6 +3868,13 @@
args->downTime, args->pointerCount,
args->pointerProperties, args->pointerCoords, 0, 0);
+ if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
+ IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
+ !mInputFilterEnabled) {
+ const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
+ mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
+ }
+
needWake = enqueueInboundEventLocked(std::move(newEntry));
mLock.unlock();
} // release lock
@@ -4315,22 +4296,22 @@
}
}
-const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
+const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
int32_t displayId) const {
- static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
+ static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
auto it = mWindowHandlesByDisplay.find(displayId);
return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
}
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
const sp<IBinder>& windowHandleToken) const {
if (windowHandleToken == nullptr) {
return nullptr;
}
for (auto& it : mWindowHandlesByDisplay) {
- const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
- for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
+ for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
if (windowHandle->getToken() == windowHandleToken) {
return windowHandle;
}
@@ -4339,13 +4320,13 @@
return nullptr;
}
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
- int displayId) const {
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
+ int displayId) const {
if (windowHandleToken == nullptr) {
return nullptr;
}
- for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+ for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
if (windowHandle->getToken() == windowHandleToken) {
return windowHandle;
}
@@ -4353,11 +4334,11 @@
return nullptr;
}
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
- const sp<InputWindowHandle>& windowHandle) const {
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
+ const sp<WindowInfoHandle>& windowHandle) const {
for (auto& it : mWindowHandlesByDisplay) {
- const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
- for (const sp<InputWindowHandle>& handle : windowHandles) {
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
+ for (const sp<WindowInfoHandle>& handle : windowHandles) {
if (handle->getId() == windowHandle->getId() &&
handle->getToken() == windowHandle->getToken()) {
if (windowHandle->getInfo()->displayId != it.first) {
@@ -4373,15 +4354,15 @@
return nullptr;
}
-sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
+sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
return getWindowHandleLocked(focusedToken, displayId);
}
-bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
+bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
const bool noInputChannel =
- windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+ windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
if (connection != nullptr && noInputChannel) {
ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
@@ -4411,8 +4392,8 @@
}
void InputDispatcher::updateWindowHandlesForDisplayLocked(
- const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
- if (inputWindowHandles.empty()) {
+ const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
+ if (windowInfoHandles.empty()) {
// Remove all handles on a display if there are no windows left.
mWindowHandlesByDisplay.erase(displayId);
return;
@@ -4420,26 +4401,25 @@
// Since we compare the pointer of input window handles across window updates, we need
// to make sure the handle object for the same window stays unchanged across updates.
- const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
- std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
- for (const sp<InputWindowHandle>& handle : oldHandles) {
+ const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
+ std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
+ for (const sp<WindowInfoHandle>& handle : oldHandles) {
oldHandlesById[handle->getId()] = handle;
}
- std::vector<sp<InputWindowHandle>> newHandles;
- for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
+ std::vector<sp<WindowInfoHandle>> newHandles;
+ for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
if (!handle->updateInfo()) {
// handle no longer valid
continue;
}
- const InputWindowInfo* info = handle->getInfo();
- if ((getInputChannelLocked(handle->getToken()) == nullptr &&
- info->portalToDisplayId == ADISPLAY_ID_NONE)) {
+ const WindowInfo* info = handle->getInfo();
+ if (getInputChannelLocked(handle->getToken()) == nullptr) {
const bool noInputChannel =
- info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
- const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
- !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
+ info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
+ const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
+ !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
if (canReceiveInput && !noInputChannel) {
ALOGV("Window handle %s has no registered input channel",
handle->getName().c_str());
@@ -4455,7 +4435,7 @@
if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
(oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
- const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
+ const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
oldHandle->updateFrom(handle);
newHandles.push_back(oldHandle);
} else {
@@ -4468,7 +4448,7 @@
}
void InputDispatcher::setInputWindows(
- const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
+ const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
{ // acquire lock
std::scoped_lock _l(mLock);
for (const auto& [displayId, handles] : handlesPerDisplay) {
@@ -4487,19 +4467,19 @@
* For removed handle, check if need to send a cancel event if already in touch.
*/
void InputDispatcher::setInputWindowsLocked(
- const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
+ const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
if (DEBUG_FOCUS) {
std::string windowList;
- for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
+ for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
windowList += iwh->getName() + " ";
}
ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
}
// Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
- for (const sp<InputWindowHandle>& window : inputWindowHandles) {
+ for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
const bool noInputWindow =
- window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+ window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
if (noInputWindow && window->getToken() != nullptr) {
ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
window->getName().c_str());
@@ -4508,18 +4488,18 @@
}
// Copy old handles for release if they are no longer present.
- const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
// Save the old windows' orientation by ID before it gets updated.
std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
- for (const sp<InputWindowHandle>& handle : oldWindowHandles) {
+ for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
oldWindowOrientations.emplace(handle->getId(),
handle->getInfo()->transform.getOrientation());
}
- updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
+ updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
- const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+ const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
if (mLastHoverWindowHandle &&
std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
windowHandles.end()) {
@@ -4568,8 +4548,8 @@
if (isPerWindowInputRotationEnabled()) {
// Determine if the orientation of any of the input windows have changed, and cancel all
// pointer events if necessary.
- for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
- const sp<InputWindowHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
+ for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
+ const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
if (newWindowHandle != nullptr &&
newWindowHandle->getInfo()->transform.getOrientation() !=
oldWindowOrientations[oldWindowHandle->getId()]) {
@@ -4588,7 +4568,7 @@
// This ensures that unused input channels are released promptly.
// Otherwise, they might stick around until the window handle is destroyed
// which might not happen until the next GC.
- for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+ for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
if (DEBUG_FOCUS) {
ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
@@ -4598,7 +4578,7 @@
// check for window flags when windows are going away.
// TODO(b/157929241) : delete this. This is only needed temporarily
// in order to gather some data about the flag usage
- if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
+ if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
oldWindowHandle->getName().c_str());
if (mCompatService != nullptr) {
@@ -4788,8 +4768,8 @@
{ // acquire lock
std::scoped_lock _l(mLock);
- sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
- sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
+ sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
+ sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
ALOGW("Cannot transfer focus because from or to window not found.");
return false;
@@ -4867,7 +4847,7 @@
{ // acquire lock
std::scoped_lock _l(mLock);
- sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
+ sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
if (toWindowHandle == nullptr) {
ALOGW("Could not find window associated with token=%p", destChannelToken.get());
return false;
@@ -4934,7 +4914,7 @@
std::string windowName = "None";
if (mWindowTokenWithPointerCapture) {
- const sp<InputWindowHandle> captureWindowHandle =
+ const sp<WindowInfoHandle> captureWindowHandle =
getWindowHandleLocked(mWindowTokenWithPointerCapture);
windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
: "token has capture without window";
@@ -4987,14 +4967,6 @@
} else {
dump += INDENT3 "Windows: <none>\n";
}
- if (!state.portalWindows.empty()) {
- dump += INDENT3 "Portal windows:\n";
- for (size_t i = 0; i < state.portalWindows.size(); i++) {
- const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
- dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
- portalWindowHandle->getName().c_str());
- }
- }
}
} else {
dump += INDENT "TouchStates: <no displays touched>\n";
@@ -5007,16 +4979,16 @@
if (!mWindowHandlesByDisplay.empty()) {
for (auto& it : mWindowHandlesByDisplay) {
- const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
+ const std::vector<sp<WindowInfoHandle>> windowHandles = it.second;
dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
if (!windowHandles.empty()) {
dump += INDENT2 "Windows:\n";
for (size_t i = 0; i < windowHandles.size(); i++) {
- const sp<InputWindowHandle>& windowHandle = windowHandles[i];
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
+ const WindowInfo* windowInfo = windowHandle->getInfo();
dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
- "portalToDisplayId=%d, paused=%s, focusable=%s, "
+ "paused=%s, focusable=%s, "
"hasWallpaper=%s, visible=%s, alpha=%.2f, "
"flags=%s, type=%s, "
"frame=[%d,%d][%d,%d], globalScale=%f, "
@@ -5024,8 +4996,7 @@
"applicationInfo.token=%s, "
"touchableRegion=",
i, windowInfo->name.c_str(), windowInfo->id,
- windowInfo->displayId, windowInfo->portalToDisplayId,
- toString(windowInfo->paused),
+ windowInfo->displayId, toString(windowInfo->paused),
toString(windowInfo->focusable),
toString(windowInfo->hasWallpaper),
toString(windowInfo->visible), windowInfo->alpha,
@@ -5394,7 +5365,7 @@
{ // acquire lock
std::scoped_lock _l(mLock);
if (DEBUG_FOCUS) {
- const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
+ const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
windowHandle != nullptr ? windowHandle->getName().c_str()
: "token without window");
@@ -5565,7 +5536,7 @@
postCommandLocked(std::move(commandEntry));
}
-void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
+void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
const std::string& reason) {
const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
updateLastAnrStateLocked(windowLabel, reason);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 9edf41c..32a467e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -37,10 +37,10 @@
#include <attestation/HmacKeyManager.h>
#include <com/android/internal/compat/IPlatformCompatNative.h>
+#include <gui/InputApplication.h>
+#include <gui/WindowInfo.h>
#include <input/Input.h>
-#include <input/InputApplication.h>
#include <input/InputTransport.h>
-#include <input/InputWindow.h>
#include <limits.h>
#include <stddef.h>
#include <ui/Region.h>
@@ -109,8 +109,9 @@
std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
- void setInputWindows(const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
- handlesPerDisplay) override;
+ void setInputWindows(
+ const std::unordered_map<int32_t, std::vector<sp<android::gui::WindowInfoHandle>>>&
+ handlesPerDisplay) override;
void setFocusedApplication(
int32_t displayId,
const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) override;
@@ -127,7 +128,7 @@
base::Result<std::unique_ptr<InputChannel>> createInputChannel(
const std::string& name) override;
- void setFocusedWindow(const FocusRequest&) override;
+ void setFocusedWindow(const android::gui::FocusRequest&) override;
base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
bool isGestureMonitor,
const std::string& name,
@@ -190,8 +191,8 @@
void enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
const std::string& reason) REQUIRES(mLock);
// Enqueues a drag event.
- void enqueueDragEventLocked(const sp<InputWindowHandle>& windowToken, bool isExiting,
- const MotionEntry& motionEntry) REQUIRES(mLock);
+ void enqueueDragEventLocked(const sp<android::gui::WindowInfoHandle>& windowToken,
+ bool isExiting, const MotionEntry& motionEntry) REQUIRES(mLock);
// Adds an event to a queue of recent events for debugging purposes.
void addRecentEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);
@@ -208,11 +209,11 @@
// to transfer focus to a new application.
std::shared_ptr<EventEntry> mNextUnblockedEvent GUARDED_BY(mLock);
- sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y,
- TouchState* touchState,
- bool addOutsideTargets = false,
- bool addPortalWindows = false,
- bool ignoreDragWindow = false) REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x,
+ int32_t y, TouchState* touchState,
+ bool addOutsideTargets = false,
+ bool ignoreDragWindow = false)
+ REQUIRES(mLock);
sp<Connection> getConnectionLocked(const sp<IBinder>& inputConnectionToken) const
REQUIRES(mLock);
@@ -314,33 +315,36 @@
float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock);
android::os::BlockUntrustedTouchesMode mBlockUntrustedTouchesMode GUARDED_BY(mLock);
- std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
- GUARDED_BY(mLock);
- void setInputWindowsLocked(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
- int32_t displayId) REQUIRES(mLock);
+ std::unordered_map<int32_t, std::vector<sp<android::gui::WindowInfoHandle>>>
+ mWindowHandlesByDisplay GUARDED_BY(mLock);
+ void setInputWindowsLocked(
+ const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
+ int32_t displayId) REQUIRES(mLock);
// Get a reference to window handles by display, return an empty vector if not found.
- const std::vector<sp<InputWindowHandle>>& getWindowHandlesLocked(int32_t displayId) const
- REQUIRES(mLock);
- sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const
- REQUIRES(mLock);
+ const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesLocked(
+ int32_t displayId) const REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
+ const sp<IBinder>& windowHandleToken) const REQUIRES(mLock);
// Same function as above, but faster. Since displayId is provided, this avoids the need
// to loop through all displays.
- sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
- int displayId) const REQUIRES(mLock);
- sp<InputWindowHandle> getWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const
- REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
+ int displayId) const REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
+ const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
std::shared_ptr<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const
REQUIRES(mLock);
- sp<InputWindowHandle> getFocusedWindowHandleLocked(int displayId) const REQUIRES(mLock);
- bool hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked(int displayId) const
+ REQUIRES(mLock);
+ bool hasResponsiveConnectionLocked(android::gui::WindowInfoHandle& windowHandle) const
+ REQUIRES(mLock);
/*
* Validate and update InputWindowHandles for a given display.
*/
void updateWindowHandlesForDisplayLocked(
- const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId)
- REQUIRES(mLock);
+ const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
+ int32_t displayId) REQUIRES(mLock);
std::unordered_map<int32_t, TouchState> mTouchStatesByDisplay GUARDED_BY(mLock);
std::unique_ptr<DragState> mDragState GUARDED_BY(mLock);
@@ -471,7 +475,7 @@
AnrTracker mAnrTracker GUARDED_BY(mLock);
// Contains the last window which received a hover event.
- sp<InputWindowHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
+ sp<android::gui::WindowInfoHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
void cancelEventsForAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) REQUIRES(mLock);
@@ -489,21 +493,20 @@
android::os::InputEventInjectionResult findTouchedWindowTargetsLocked(
nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) REQUIRES(mLock);
- std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(
- int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const
+ std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(int32_t displayId) const
REQUIRES(mLock);
std::vector<TouchedMonitor> selectResponsiveMonitorsLocked(
const std::vector<TouchedMonitor>& gestureMonitors) const REQUIRES(mLock);
- void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
- BitSet32 pointerIds, std::vector<InputTarget>& inputTargets)
- REQUIRES(mLock);
+ void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+ int32_t targetFlags, BitSet32 pointerIds,
+ std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
void addMonitoringTargetLocked(const Monitor& monitor, float xOffset, float yOffset,
std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
float xOffset = 0, float yOffset = 0) REQUIRES(mLock);
void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
- bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+ bool checkInjectionPermission(const sp<android::gui::WindowInfoHandle>& windowHandle,
const InjectionState* injectionState);
// Enqueue a drag event if needed, and update the touch state.
// Uses findTouchedWindowTargetsLocked to make the decision
@@ -518,15 +521,18 @@
std::vector<std::string> debugInfo;
};
- TouchOcclusionInfo computeTouchOcclusionInfoLocked(const sp<InputWindowHandle>& windowHandle,
- int32_t x, int32_t y) const REQUIRES(mLock);
+ TouchOcclusionInfo computeTouchOcclusionInfoLocked(
+ const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const
+ REQUIRES(mLock);
bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
- bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle, int32_t x,
- int32_t y) const REQUIRES(mLock);
- bool isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const REQUIRES(mLock);
- std::string dumpWindowForTouchOcclusion(const InputWindowInfo* info, bool isTouchWindow) const;
+ bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+ int32_t x, int32_t y) const REQUIRES(mLock);
+ bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
+ REQUIRES(mLock);
+ std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
+ bool isTouchWindow) const;
std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
- const sp<InputWindowHandle>& windowHandle);
+ const sp<android::gui::WindowInfoHandle>& windowHandle);
// Manage the dispatch cycle for a single connection.
// These methods are deliberately not Interruptible because doing all of the work
@@ -605,8 +611,8 @@
void onAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
void onAnrLocked(std::shared_ptr<InputApplicationHandle> application) REQUIRES(mLock);
void onUntrustedTouchLocked(const std::string& obscuringPackage) REQUIRES(mLock);
- void updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)
- REQUIRES(mLock);
+ void updateLastAnrStateLocked(const sp<android::gui::WindowInfoHandle>& window,
+ const std::string& reason) REQUIRES(mLock);
void updateLastAnrStateLocked(const InputApplicationHandle& application,
const std::string& reason) REQUIRES(mLock);
void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason)
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index 1c4980b..7c463c8 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -17,6 +17,7 @@
#ifndef _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H
#define _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H
+#include <gui/constants.h>
#include <input/InputTransport.h>
#include <ui/Transform.h>
#include <utils/BitSet.h>
@@ -100,8 +101,11 @@
// (ignored for KeyEvents)
float globalScaleFactor = 1.0f;
+ // Current display orientation
+ uint32_t displayOrientation = ui::Transform::ROT_0;
+
// Display-size in its natural rotation. Used for compatibility transform of raw coordinates.
- int2 displaySize = {AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE};
+ int2 displaySize = {INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE};
// The subset of pointer ids to include in motion events dispatched to this input target
// if FLAG_SPLIT is set.
diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp
index d634dcd..52f189c 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -50,13 +50,12 @@
* key-value pair. Equivalent to the imaginary std api std::multimap::erase(key, value).
*/
template <typename K, typename V>
-static void eraseByKeyAndValue(std::multimap<K, V>& map, K key, V value) {
- auto iterpair = map.equal_range(key);
-
- for (auto it = iterpair.first; it != iterpair.second; ++it) {
+static void eraseByValue(std::multimap<K, V>& map, const V& value) {
+ for (auto it = map.begin(); it != map.end();) {
if (it->second == value) {
- map.erase(it);
- break;
+ it = map.erase(it);
+ } else {
+ it++;
}
}
}
@@ -76,9 +75,7 @@
// confuse us by reporting the rest of the timeline for one of them. This should happen
// rarely, so we won't lose much data
mTimelines.erase(it);
- // In case we have another input event with a different id and at the same eventTime,
- // only erase this specific inputEventId.
- eraseByKeyAndValue(mEventTimes, eventTime, inputEventId);
+ eraseByValue(mEventTimes, inputEventId);
return;
}
mTimelines.emplace(inputEventId, InputEventTimeline(isDown, eventTime, readTime));
@@ -90,7 +87,8 @@
nsecs_t finishTime) {
const auto it = mTimelines.find(inputEventId);
if (it == mTimelines.end()) {
- // It's possible that an app sends a bad (or late)'Finish' signal, since it's free to do
+ // This could happen if we erased this event when duplicate events were detected. It's
+ // also possible that an app sent a bad (or late) 'Finish' signal, since it's free to do
// anything in its process. Just drop the report and move on.
return;
}
@@ -120,7 +118,8 @@
std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline) {
const auto it = mTimelines.find(inputEventId);
if (it == mTimelines.end()) {
- // It's possible that an app sends a bad (or late) 'Timeline' signal, since it's free to do
+ // This could happen if we erased this event when duplicate events were detected. It's
+ // also possible that an app sent a bad (or late) 'Timeline' signal, since it's free to do
// anything in its process. Just drop the report and move on.
return;
}
@@ -166,14 +165,6 @@
}
}
-void LatencyTracker::reportNow() {
- for (const auto& [inputEventId, timeline] : mTimelines) {
- mTimelineProcessor->processTimeline(timeline);
- }
- mTimelines.clear();
- mEventTimes.clear();
-}
-
std::string LatencyTracker::dump(const char* prefix) {
return StringPrintf("%sLatencyTracker:\n", prefix) +
StringPrintf("%s mTimelines.size() = %zu\n", prefix, mTimelines.size()) +
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index 289b8ed..4b0c618 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -43,6 +43,12 @@
LatencyTracker(InputEventTimelineProcessor* processor);
/**
* Start keeping track of an event identified by inputEventId. This must be called first.
+ * If duplicate events are encountered (events that have the same eventId), none of them will be
+ * tracked. This is because there is not enough information to correctly track them. The api's
+ * 'trackFinishedEvent' and 'trackGraphicsLatency' only contain the inputEventId, and not the
+ * eventTime. Even if eventTime was provided, there would still be a possibility of having
+ * duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
+ * must drop all duplicate data.
*/
void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime);
void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
@@ -50,14 +56,6 @@
void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
- /**
- * Report all collected events immediately, even if some of them are currently incomplete
- * and may receive 'trackFinishedEvent' or 'trackGraphicsLatency' calls in the future.
- * This is useful for tests. Otherwise, tests would have to inject additional "future" events,
- * which is not convenient.
- */
- void reportNow();
-
std::string dump(const char* prefix);
private:
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index 81b3cf0..b7ed658 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
#include "InputTarget.h"
#include "TouchState.h"
-using android::InputWindowHandle;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
namespace android::inputdispatcher {
@@ -36,7 +37,6 @@
source = 0;
displayId = ADISPLAY_ID_NONE;
windows.clear();
- portalWindows.clear();
gestureMonitors.clear();
}
@@ -47,11 +47,10 @@
source = other.source;
displayId = other.displayId;
windows = other.windows;
- portalWindows = other.portalWindows;
gestureMonitors = other.gestureMonitors;
}
-void TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
+void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
BitSet32 pointerIds) {
if (targetFlags & InputTarget::FLAG_SPLIT) {
split = true;
@@ -76,16 +75,6 @@
windows.push_back(touchedWindow);
}
-void TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
- size_t numWindows = portalWindows.size();
- for (size_t i = 0; i < numWindows; i++) {
- if (portalWindows[i] == windowHandle) {
- return;
- }
- }
- portalWindows.push_back(windowHandle);
-}
-
void TouchState::addGestureMonitors(const std::vector<TouchedMonitor>& newMonitors) {
const size_t newSize = gestureMonitors.size() + newMonitors.size();
gestureMonitors.reserve(newSize);
@@ -118,10 +107,9 @@
void TouchState::filterNonMonitors() {
windows.clear();
- portalWindows.clear();
}
-sp<InputWindowHandle> TouchState::getFirstForegroundWindowHandle() const {
+sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
for (size_t i = 0; i < windows.size(); i++) {
const TouchedWindow& window = windows[i];
if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
@@ -137,7 +125,7 @@
for (const TouchedWindow& window : windows) {
if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
if (haveSlipperyForegroundWindow ||
- !window.windowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
+ !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
return false;
}
haveSlipperyForegroundWindow = true;
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index 623c6a8..579b868 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -22,7 +22,9 @@
namespace android {
-class InputWindowHandle;
+namespace gui {
+class WindowInfoHandle;
+}
namespace inputdispatcher {
@@ -34,25 +36,20 @@
int32_t displayId; // id to the display that currently has a touch, others are rejected
std::vector<TouchedWindow> windows;
- // This collects the portal windows that the touch has gone through. Each portal window
- // targets a display (embedded display for most cases). With this info, we can add the
- // monitoring channels of the displays touched.
- std::vector<sp<android::InputWindowHandle>> portalWindows;
-
std::vector<TouchedMonitor> gestureMonitors;
TouchState();
~TouchState();
void reset();
void copyFrom(const TouchState& other);
- void addOrUpdateWindow(const sp<android::InputWindowHandle>& windowHandle, int32_t targetFlags,
- BitSet32 pointerIds);
- void addPortalWindow(const sp<android::InputWindowHandle>& windowHandle);
+ void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
+ int32_t targetFlags, BitSet32 pointerIds);
+ void addPortalWindow(const sp<android::gui::WindowInfoHandle>& windowHandle);
void addGestureMonitors(const std::vector<TouchedMonitor>& monitors);
void removeWindowByToken(const sp<IBinder>& token);
void filterNonAsIsTouchWindows();
void filterNonMonitors();
- sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
+ sp<android::gui::WindowInfoHandle> getFirstForegroundWindowHandle() const;
bool isSlippery() const;
};
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index 8713aa3..4c31ec3 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -19,13 +19,15 @@
namespace android {
-class InputWindowHandle;
+namespace gui {
+class WindowInfoHandle;
+}
namespace inputdispatcher {
// Focus tracking for touch.
struct TouchedWindow {
- sp<android::InputWindowHandle> windowHandle;
+ sp<gui::WindowInfoHandle> windowHandle;
int32_t targetFlags;
BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
};
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 43428a0..80db035 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,18 +19,17 @@
#include <InputListener.h>
#include <android-base/result.h>
-#include <android/FocusRequest.h>
+#include <android/gui/FocusRequest.h>
#include <android/os/BlockUntrustedTouchesMode.h>
#include <android/os/ISetInputWindowsListener.h>
#include <android/os/InputEventInjectionResult.h>
#include <android/os/InputEventInjectionSync.h>
-#include <input/InputApplication.h>
+#include <gui/InputApplication.h>
+#include <gui/WindowInfo.h>
#include <input/InputDevice.h>
#include <input/InputTransport.h>
-#include <input/InputWindow.h>
#include <unordered_map>
-
namespace android {
/* Notifies the system about input events generated by the input reader.
@@ -91,7 +90,7 @@
* This method may be called on any thread (usually by the input manager).
*/
virtual void setInputWindows(
- const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+ const std::unordered_map<int32_t, std::vector<sp<gui::WindowInfoHandle>>>&
handlesPerDisplay) = 0;
/* Sets the focused application on the given display.
@@ -162,7 +161,7 @@
/**
* Sets focus on the specified window.
*/
- virtual void setFocusedWindow(const FocusRequest&) = 0;
+ virtual void setFocusedWindow(const gui::FocusRequest&) = 0;
/**
* Creates an input channel that may be used as targets for input events.
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 219f45a..ebfcbe1 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -20,8 +20,8 @@
#include "InputDispatcherConfiguration.h"
#include <binder/IBinder.h>
+#include <gui/InputApplication.h>
#include <input/Input.h>
-#include <input/InputApplication.h>
#include <utils/RefBase.h>
namespace android {
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 8112038..c05ff39 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -30,6 +30,8 @@
#include <utils/String8.h>
#include <utils/StrongPointer.h>
+using android::gui::FocusRequest;
+using android::gui::WindowInfo;
using android::os::BnInputFlinger;
using android::os::ISetInputWindowsListener;
@@ -44,7 +46,7 @@
InputFlinger() ANDROID_API;
status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status setInputWindows(const std::vector<InputWindowInfo>&,
+ binder::Status setInputWindows(const std::vector<WindowInfo>&,
const sp<ISetInputWindowsListener>&) override {
return binder::Status::ok();
}
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index 7db32e3..ee7b392 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -71,6 +71,7 @@
"libstatslog",
"libui",
"libutils",
+ "InputFlingerProperties",
],
static_libs: [
"libc++fs",
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index b19b419..68d5e7c 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -63,9 +63,9 @@
namespace android {
-static const char* DEVICE_PATH = "/dev/input";
+static const char* DEVICE_INPUT_PATH = "/dev/input";
// v4l2 devices go directly into /dev
-static const char* VIDEO_DEVICE_PATH = "/dev";
+static const char* DEVICE_PATH = "/dev";
static constexpr size_t OBFUSCATED_LENGTH = 8;
@@ -685,15 +685,23 @@
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
mINotifyFd = inotify_init();
- mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
- LOG_ALWAYS_FATAL_IF(mInputWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
- strerror(errno));
- if (isV4lScanningEnabled()) {
- mVideoWd = inotify_add_watch(mINotifyFd, VIDEO_DEVICE_PATH, IN_DELETE | IN_CREATE);
- LOG_ALWAYS_FATAL_IF(mVideoWd < 0, "Could not register INotify for %s: %s",
- VIDEO_DEVICE_PATH, strerror(errno));
+
+ std::error_code errorCode;
+ bool isDeviceInotifyAdded = false;
+ if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
+ addDeviceInputInotify();
} else {
- mVideoWd = -1;
+ addDeviceInotify();
+ isDeviceInotifyAdded = true;
+ if (errorCode) {
+ ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
+ errorCode.message().c_str());
+ }
+ }
+
+ if (isV4lScanningEnabled() && !isDeviceInotifyAdded) {
+ addDeviceInotify();
+ } else {
ALOGI("Video device scanning disabled");
}
@@ -733,6 +741,23 @@
::close(mWakeWritePipeFd);
}
+/**
+ * On devices that don't have any input devices (like some development boards), the /dev/input
+ * directory will be absent. However, the user may still plug in an input device at a later time.
+ * Add watch for contents of /dev/input only when /dev/input appears.
+ */
+void EventHub::addDeviceInputInotify() {
+ mDeviceInputWd = inotify_add_watch(mINotifyFd, DEVICE_INPUT_PATH, IN_DELETE | IN_CREATE);
+ LOG_ALWAYS_FATAL_IF(mDeviceInputWd < 0, "Could not register INotify for %s: %s",
+ DEVICE_INPUT_PATH, strerror(errno));
+}
+
+void EventHub::addDeviceInotify() {
+ mDeviceWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
+ LOG_ALWAYS_FATAL_IF(mDeviceWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
+ strerror(errno));
+}
+
InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
std::scoped_lock _l(mLock);
Device* device = getDeviceLocked(deviceId);
@@ -1739,14 +1764,24 @@
}
void EventHub::scanDevicesLocked() {
- status_t result = scanDirLocked(DEVICE_PATH);
- if (result < 0) {
- ALOGE("scan dir failed for %s", DEVICE_PATH);
+ status_t result;
+ std::error_code errorCode;
+
+ if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
+ result = scanDirLocked(DEVICE_INPUT_PATH);
+ if (result < 0) {
+ ALOGE("scan dir failed for %s", DEVICE_INPUT_PATH);
+ }
+ } else {
+ if (errorCode) {
+ ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
+ errorCode.message().c_str());
+ }
}
if (isV4lScanningEnabled()) {
- result = scanVideoDirLocked(VIDEO_DEVICE_PATH);
+ result = scanVideoDirLocked(DEVICE_PATH);
if (result != OK) {
- ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
+ ALOGE("scan video dir failed for %s", DEVICE_PATH);
}
}
if (mDevices.find(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) == mDevices.end()) {
@@ -2357,23 +2392,25 @@
while (res >= (int)sizeof(*event)) {
event = (struct inotify_event*)(event_buf + event_pos);
if (event->len) {
- if (event->wd == mInputWd) {
- std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
+ if (event->wd == mDeviceInputWd) {
+ std::string filename = std::string(DEVICE_INPUT_PATH) + "/" + event->name;
if (event->mask & IN_CREATE) {
openDeviceLocked(filename);
} else {
ALOGI("Removing device '%s' due to inotify event\n", filename.c_str());
closeDeviceByPathLocked(filename);
}
- } else if (event->wd == mVideoWd) {
+ } else if (event->wd == mDeviceWd) {
if (isV4lTouchNode(event->name)) {
- std::string filename = std::string(VIDEO_DEVICE_PATH) + "/" + event->name;
+ std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
if (event->mask & IN_CREATE) {
openVideoDeviceLocked(filename);
} else {
ALOGI("Removing video device '%s' due to inotify event", filename.c_str());
closeVideoDeviceByPathLocked(filename);
}
+ } else if (strcmp(event->name, "input") == 0 && event->mask & IN_CREATE) {
+ addDeviceInputInotify();
}
} else {
LOG_ALWAYS_FATAL("Unexpected inotify event, wd = %i", event->wd);
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 7af014c..1e9ec54 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -18,7 +18,7 @@
#include "InputDevice.h"
-#include <input/Flags.h>
+#include <ftl/Flags.h>
#include <algorithm>
#include "CursorInputMapper.h"
diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp
index 16251ee..9c8a29a 100644
--- a/services/inputflinger/reader/controller/PeripheralController.cpp
+++ b/services/inputflinger/reader/controller/PeripheralController.cpp
@@ -19,8 +19,8 @@
#include "../Macros.h"
+#include <ftl/NamedEnum.h>
#include "PeripheralController.h"
-#include "input/NamedEnum.h"
// Log detailed debug messages about input device lights.
static constexpr bool DEBUG_LIGHT_DETAILS = false;
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 410a706..3c3f88e 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -22,7 +22,7 @@
#include <unordered_map>
#include <vector>
-#include <input/Flags.h>
+#include <ftl/Flags.h>
#include <filesystem>
#include <batteryservice/BatteryService.h>
@@ -663,6 +663,9 @@
const std::unordered_map<int32_t, RawLightInfo>& getLightInfoLocked(int32_t deviceId) const
REQUIRES(mLock);
+ void addDeviceInputInotify();
+ void addDeviceInotify();
+
// Protect all internal state.
mutable std::mutex mLock;
@@ -702,8 +705,8 @@
int mWakeReadPipeFd;
int mWakeWritePipeFd;
- int mInputWd;
- int mVideoWd;
+ int mDeviceInputWd;
+ int mDeviceWd = -1;
// Maximum number of signalled FDs to handle at a time.
static const int EPOLL_MAX_EVENTS = 16;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 2f2eba7..f32472d 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -17,8 +17,8 @@
#ifndef _UI_INPUTREADER_INPUT_DEVICE_H
#define _UI_INPUTREADER_INPUT_DEVICE_H
+#include <ftl/Flags.h>
#include <input/DisplayViewport.h>
-#include <input/Flags.h>
#include <input/InputDevice.h>
#include <input/PropertyMap.h>
#include <stdint.h>
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 7ac2dec..a507632 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -303,7 +303,7 @@
* the device
*/
mDeviceEnabled = false;
- for (const auto& [sensorType, sensor] : mSensors) {
+ for (const auto& [_, sensor] : mSensors) {
// If any sensor is on we will turn on the device.
if (sensor.enabled) {
mDeviceEnabled = true;
diff --git a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
index da0fea4..4c5ff63 100644
--- a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
+++ b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
@@ -17,7 +17,7 @@
#ifndef _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
#define _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
-#include <android-base/properties.h>
+#include <InputFlingerProperties.sysprop.h>
#include <input/DisplayViewport.h>
#include <stdint.h>
@@ -34,7 +34,7 @@
// un-rotated coordinate space.
static bool isPerWindowInputRotationEnabled() {
static const bool PER_WINDOW_INPUT_ROTATION =
- base::GetBoolProperty("persist.debug.per_window_input_rotation", false);
+ sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
return PER_WINDOW_INPUT_ROTATION;
}
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 962d8d2..af02844 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -18,7 +18,7 @@
#include "../Macros.h"
// clang-format on
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
#include "TouchInputMapper.h"
#include "CursorButtonAccumulator.h"
diff --git a/services/inputflinger/sysprop/Android.bp b/services/inputflinger/sysprop/Android.bp
new file mode 100644
index 0000000..b9d65ee
--- /dev/null
+++ b/services/inputflinger/sysprop/Android.bp
@@ -0,0 +1,15 @@
+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"],
+}
+
+sysprop_library {
+ name: "InputFlingerProperties",
+ srcs: ["*.sysprop"],
+ api_packages: ["android.sysprop"],
+ property_owner: "Platform",
+}
diff --git a/services/inputflinger/sysprop/InputFlingerProperties.sysprop b/services/inputflinger/sysprop/InputFlingerProperties.sysprop
new file mode 100644
index 0000000..1c7e724
--- /dev/null
+++ b/services/inputflinger/sysprop/InputFlingerProperties.sysprop
@@ -0,0 +1,27 @@
+# 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.
+
+module: "android.sysprop.InputFlingerProperties"
+owner: Platform
+
+# When per-window-input-rotation is enabled, InputReader works in the un-rotated
+# display coordinate space, and the display rotation is encoded as part of the
+# input window transform that is sent from SurfaceFlinger to InputDispatcher.
+prop {
+ api_name: "per_window_input_rotation"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ prop_name: "persist.debug.per_window_input_rotation"
+}
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 918e1be..e686924 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -52,6 +52,7 @@
],
aidl: {
include_dirs: [
+ "frameworks/native/libs/gui",
"frameworks/native/libs/input",
],
},
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 9051ff1..8c0edca 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -26,9 +26,12 @@
// atest inputflinger_tests:FocusResolverTest
+using android::gui::FocusRequest;
+using android::gui::WindowInfoHandle;
+
namespace android::inputdispatcher {
-class FakeWindowHandle : public InputWindowHandle {
+class FakeWindowHandle : public WindowInfoHandle {
public:
FakeWindowHandle(const std::string& name, const sp<IBinder>& token, bool focusable,
bool visible) {
@@ -47,7 +50,7 @@
sp<IBinder> focusableWindowToken = new BBinder();
sp<IBinder> invisibleWindowToken = new BBinder();
sp<IBinder> unfocusableWindowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
windows.push_back(new FakeWindowHandle("Focusable", focusableWindowToken, true /* focusable */,
true /* visible */));
windows.push_back(new FakeWindowHandle("Invisible", invisibleWindowToken, true /* focusable */,
@@ -82,7 +85,7 @@
sp<IBinder> focusableWindowToken = new BBinder();
sp<IBinder> invisibleWindowToken = new BBinder();
sp<IBinder> unfocusableWindowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
windows.push_back(new FakeWindowHandle("Mirror1", focusableWindowToken, true /* focusable */,
true /* visible */));
windows.push_back(new FakeWindowHandle("Mirror1", focusableWindowToken, true /* focusable */,
@@ -120,7 +123,7 @@
TEST(FocusResolverTest, SetInputWindows) {
sp<IBinder> focusableWindowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
sp<FakeWindowHandle> window = new FakeWindowHandle("Focusable", focusableWindowToken,
true /* focusable */, true /* visible */);
windows.push_back(window);
@@ -142,7 +145,7 @@
TEST(FocusResolverTest, FocusRequestsCanBePending) {
sp<IBinder> invisibleWindowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
sp<FakeWindowHandle> invisibleWindow =
new FakeWindowHandle("Invisible", invisibleWindowToken, true /* focusable */,
@@ -166,7 +169,7 @@
TEST(FocusResolverTest, FocusRequestsArePersistent) {
sp<IBinder> windowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
sp<FakeWindowHandle> window = new FakeWindowHandle("Test Window", windowToken,
false /* focusable */, true /* visible */);
@@ -207,7 +210,7 @@
TEST(FocusResolverTest, ConditionalFocusRequestsAreNotPersistent) {
sp<IBinder> hostWindowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
sp<FakeWindowHandle> hostWindow =
new FakeWindowHandle("Host Window", hostWindowToken, true /* focusable */,
@@ -258,7 +261,7 @@
}
TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
sp<IBinder> windowToken = new BBinder();
- std::vector<sp<InputWindowHandle>> windows;
+ std::vector<sp<WindowInfoHandle>> windows;
sp<FakeWindowHandle> window = new FakeWindowHandle("Test Window", windowToken,
true /* focusable */, true /* visible */);
diff --git a/services/inputflinger/tests/IInputFlingerQuery.aidl b/services/inputflinger/tests/IInputFlingerQuery.aidl
index 5c8a8da..aff03bf 100644
--- a/services/inputflinger/tests/IInputFlingerQuery.aidl
+++ b/services/inputflinger/tests/IInputFlingerQuery.aidl
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-import android.FocusRequest;
import android.InputChannel;
-import android.InputWindowInfo;
+import android.gui.FocusRequest;
+import android.gui.WindowInfo;
import android.os.ISetInputWindowsListener;
/** @hide */
interface IInputFlingerQuery
{
/* Test interfaces */
- void getInputWindows(out InputWindowInfo[] inputHandles);
+ void getInputWindows(out WindowInfo[] inputHandles);
void getInputChannels(out InputChannel[] channels);
void getLastFocusRequest(out FocusRequest request);
void resetInputManager();
diff --git a/services/inputflinger/tests/InputClassifierConverter_test.cpp b/services/inputflinger/tests/InputClassifierConverter_test.cpp
index c0ada9d..f626d56 100644
--- a/services/inputflinger/tests/InputClassifierConverter_test.cpp
+++ b/services/inputflinger/tests/InputClassifierConverter_test.cpp
@@ -17,9 +17,9 @@
#include "../InputClassifierConverter.h"
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <utils/BitSet.h>
-
using namespace android::hardware::input;
namespace android {
diff --git a/services/inputflinger/tests/InputClassifier_test.cpp b/services/inputflinger/tests/InputClassifier_test.cpp
index a72df01..3a9994e 100644
--- a/services/inputflinger/tests/InputClassifier_test.cpp
+++ b/services/inputflinger/tests/InputClassifier_test.cpp
@@ -16,6 +16,7 @@
#include "../InputClassifier.h"
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include "TestInputListener.h"
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 3a9dede..f03cf8b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -29,9 +29,12 @@
#include <vector>
using android::base::StringPrintf;
+using android::gui::FocusRequest;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
using android::os::InputEventInjectionResult;
using android::os::InputEventInjectionSync;
-using android::os::TouchOcclusionMode;
using namespace android::flag_operators;
namespace android::inputdispatcher {
@@ -469,8 +472,8 @@
}
}
- void setFocusedWindow(const sp<InputWindowHandle>& window,
- const sp<InputWindowHandle>& focusedWindow = nullptr) {
+ void setFocusedWindow(const sp<WindowInfoHandle>& window,
+ const sp<WindowInfoHandle>& focusedWindow = nullptr) {
FocusRequest request;
request.token = window->getToken();
request.windowName = window->getName();
@@ -527,8 +530,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
/*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -541,9 +544,9 @@
(1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
- pointerCoords);
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
InputEventInjectionSync::NONE, 0ms, 0))
@@ -554,9 +557,9 @@
(~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
- pointerCoords);
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
InputEventInjectionSync::NONE, 0ms, 0))
@@ -568,9 +571,9 @@
(1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
- pointerCoords);
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
InputEventInjectionSync::NONE, 0ms, 0))
@@ -581,9 +584,9 @@
(~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
- pointerCoords);
+ ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
InputEventInjectionSync::NONE, 0ms, 0))
@@ -593,8 +596,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 0, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -604,8 +607,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -617,8 +620,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -629,8 +632,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -643,8 +646,8 @@
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
- AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 2, pointerProperties, pointerCoords);
ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -892,7 +895,7 @@
std::string mName;
};
-class FakeWindowHandle : public InputWindowHandle {
+class FakeWindowHandle : public WindowInfoHandle {
public:
static const int32_t WIDTH = 600;
static const int32_t HEIGHT = 800;
@@ -914,7 +917,7 @@
mInfo.token = *token;
mInfo.id = sId++;
mInfo.name = name;
- mInfo.type = InputWindowInfo::Type::APPLICATION;
+ mInfo.type = WindowInfo::Type::APPLICATION;
mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
mInfo.alpha = 1.0;
mInfo.frameLeft = 0;
@@ -948,9 +951,7 @@
void setAlpha(float alpha) { mInfo.alpha = alpha; }
- void setTouchOcclusionMode(android::os::TouchOcclusionMode mode) {
- mInfo.touchOcclusionMode = mode;
- }
+ void setTouchOcclusionMode(TouchOcclusionMode mode) { mInfo.touchOcclusionMode = mode; }
void setApplicationToken(sp<IBinder> token) { mInfo.applicationInfo.token = token; }
@@ -964,11 +965,11 @@
mInfo.addTouchableRegion(frame);
}
- void addFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags |= flags; }
+ void addFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags |= flags; }
- void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
+ void setFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags = flags; }
- void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
+ void setInputFeatures(WindowInfo::Feature features) { mInfo.inputFeatures = features; }
void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
@@ -1102,7 +1103,7 @@
void assertNoEvents() {
if (mInputReceiver == nullptr &&
- mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
+ mInfo.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL)) {
return; // Can't receive events if the window does not have input channel
}
ASSERT_NE(nullptr, mInputReceiver)
@@ -1267,8 +1268,9 @@
mAction, mActionButton, mFlags, /* edgeFlags */ 0, AMETA_NONE,
mButtonState, MotionClassification::NONE, identityTransform,
/* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
- mRawYCursorPosition, mDisplayWidth, mDisplayHeight, mEventTime, mEventTime,
- mPointers.size(), pointerProperties.data(), pointerCoords.data());
+ mRawYCursorPosition, mDisplayOrientation, mDisplayWidth, mDisplayHeight,
+ mEventTime, mEventTime, mPointers.size(), pointerProperties.data(),
+ pointerCoords.data());
return event;
}
@@ -1283,8 +1285,9 @@
int32_t mFlags{0};
float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
- int32_t mDisplayWidth{AMOTION_EVENT_INVALID_DISPLAY_SIZE};
- int32_t mDisplayHeight{AMOTION_EVENT_INVALID_DISPLAY_SIZE};
+ uint32_t mDisplayOrientation{ui::Transform::ROT_0};
+ int32_t mDisplayWidth{INVALID_DISPLAY_SIZE};
+ int32_t mDisplayHeight{INVALID_DISPLAY_SIZE};
std::vector<PointerBuilder> mPointers;
};
@@ -1410,7 +1413,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 100, 100));
- window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -1433,7 +1436,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 100, 100));
- window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
@@ -1469,11 +1472,11 @@
sp<FakeWindowHandle> windowLeft =
new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
windowLeft->setFrame(Rect(0, 0, 600, 800));
- windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> windowRight =
new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
windowRight->setFrame(Rect(600, 0, 1200, 800));
- windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -1580,7 +1583,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 1200, 800));
- window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -1662,11 +1665,11 @@
sp<FakeWindowHandle> windowLeft =
new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
windowLeft->setFrame(Rect(0, 0, 600, 800));
- windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> windowRight =
new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
windowRight->setFrame(Rect(600, 0, 1200, 800));
- windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -1860,15 +1863,13 @@
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Create a non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -1934,15 +1935,13 @@
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Create a non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2060,15 +2059,13 @@
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Create second non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2432,7 +2429,7 @@
EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
}
-TEST_F(InputDispatcherTest, NonPointerMotionEvent_NotTransformed) {
+TEST_F(InputDispatcherTest, NonPointerMotionEvent_JoystickAndTouchpadNotTransformed) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
@@ -2452,20 +2449,19 @@
// Second, we consume focus event if it is right or wrong according to onFocusChangedLocked.
window->consumeFocusEvent(true);
- constexpr const std::array nonPointerSources = {AINPUT_SOURCE_TRACKBALL,
- AINPUT_SOURCE_MOUSE_RELATIVE,
- AINPUT_SOURCE_JOYSTICK};
- for (const int source : nonPointerSources) {
- // Notify motion with a non-pointer source.
- NotifyMotionArgs motionArgs =
- generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, source, ADISPLAY_ID_DEFAULT);
+ constexpr const std::array nonTransformedSources = {std::pair(AINPUT_SOURCE_TOUCHPAD,
+ AMOTION_EVENT_ACTION_DOWN),
+ std::pair(AINPUT_SOURCE_JOYSTICK,
+ AMOTION_EVENT_ACTION_MOVE)};
+ for (const auto& [source, action] : nonTransformedSources) {
+ const NotifyMotionArgs motionArgs = generateMotionArgs(action, source, ADISPLAY_ID_DEFAULT);
mDispatcher->notifyMotion(&motionArgs);
MotionEvent* event = window->consumeMotion();
ASSERT_NE(event, nullptr);
const MotionEvent& motionEvent = *event;
- EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, motionEvent.getAction());
+ EXPECT_EQ(action, motionEvent.getAction());
EXPECT_EQ(motionArgs.pointerCount, motionEvent.getPointerCount());
float expectedX = motionArgs.pointerCoords[0].getX();
@@ -2737,8 +2733,7 @@
sp<FakeWindowHandle> slipperyExitWindow =
new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
- slipperyExitWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SLIPPERY);
+ slipperyExitWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SLIPPERY);
// Make sure this one overlaps the bottom window
slipperyExitWindow->setFrame(Rect(25, 25, 75, 75));
// Change the owner uid/pid of the window so that it is considered to be occluding the bottom
@@ -2887,6 +2882,16 @@
mWindow->assertNoEvents();
}
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterDisableInputDevice) {
+ sendAndConsumeKeyDown(DEVICE_ID);
+ expectKeyRepeatOnce(1 /*repeatCount*/);
+ NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
+ mDispatcher->notifyDeviceReset(&args);
+ mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT,
+ AKEY_EVENT_FLAG_CANCELED | AKEY_EVENT_FLAG_LONG_PRESS);
+ mWindow->assertNoEvents();
+}
+
TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
sendAndConsumeKeyDown(1 /* deviceId */);
for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
@@ -3211,9 +3216,9 @@
DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, MotionClassification::NONE,
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
- AMOTION_EVENT_INVALID_CURSOR_POSITION,
- 0 /*AMOTION_EVENT_INVALID_DISPLAY_SIZE*/,
- 0 /*AMOTION_EVENT_INVALID_DISPLAY_SIZE*/, eventTime, eventTime,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
+ 0 /*INVALID_DISPLAY_SIZE*/, 0 /*INVALID_DISPLAY_SIZE*/, eventTime,
+ eventTime,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
const int32_t additionalPolicyFlags = POLICY_FLAG_PASS_TO_USER;
@@ -3271,12 +3276,12 @@
mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
// Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
// window.
- mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mFocusedWindow =
new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
- mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -3385,14 +3390,12 @@
ADISPLAY_ID_DEFAULT);
// Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
// We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
- mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ mWindow1->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mWindow1->setFrame(Rect(0, 0, 100, 100));
mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
ADISPLAY_ID_DEFAULT, mWindow1->getToken());
- mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ mWindow2->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mWindow2->setFrame(Rect(100, 100, 200, 200));
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
@@ -3403,7 +3406,7 @@
sp<FakeWindowHandle> mWindow2;
// Helper function to convert the point from screen coordinates into the window's space
- static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
+ static PointF getPointInWindow(const WindowInfo* windowInfo, const PointF& point) {
vec2 vals = windowInfo->transform.transform(point.x, point.y);
return {vals.x, vals.y};
}
@@ -3591,7 +3594,7 @@
mWindow->setFocusable(true);
// Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
// window.
- mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -3992,16 +3995,15 @@
// Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
// window.
// Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
- mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL |
+ WindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
+ WindowInfo::Flag::SPLIT_TOUCH);
mFocusedWindow =
new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
mFocusedWindow->setDispatchingTimeout(30ms);
mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
- mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
- InputWindowInfo::Flag::SPLIT_TOUCH);
+ mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -4369,7 +4371,7 @@
"Window without input channel", ADISPLAY_ID_DEFAULT,
std::make_optional<sp<IBinder>>(nullptr) /*token*/);
- mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+ mNoInputWindow->setInputFeatures(WindowInfo::Feature::NO_INPUT_CHANNEL);
mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
// It's perfectly valid for this window to not have an associated input channel
@@ -4411,7 +4413,7 @@
"Window with input channel and NO_INPUT_CHANNEL",
ADISPLAY_ID_DEFAULT);
- mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+ mNoInputWindow->setInputFeatures(WindowInfo::Feature::NO_INPUT_CHANNEL);
mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
@@ -4711,10 +4713,10 @@
mTouchWindow.clear();
}
- sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name,
- os::TouchOcclusionMode mode, float alpha = 1.0f) {
+ sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name, TouchOcclusionMode mode,
+ float alpha = 1.0f) {
sp<FakeWindowHandle> window = getWindow(uid, name);
- window->setFlags(InputWindowInfo::Flag::NOT_TOUCHABLE);
+ window->setFlags(WindowInfo::Flag::NOT_TOUCHABLE);
window->setTouchOcclusionMode(mode);
window->setAlpha(alpha);
return window;
@@ -4828,7 +4830,7 @@
WindowWithZeroOpacityAndWatchOutside_ReceivesOutsideEvent) {
const sp<FakeWindowHandle>& w =
getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
- w->addFlags(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
touch();
@@ -4839,7 +4841,7 @@
TEST_F(InputDispatcherUntrustedTouchesTest, OutsideEvent_HasZeroCoordinates) {
const sp<FakeWindowHandle>& w =
getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
- w->addFlags(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
touch();
@@ -5093,11 +5095,11 @@
mApp = std::make_shared<FakeApplicationHandle>();
mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
mWindow->setFrame(Rect(0, 0, 100, 100));
- mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
mSecondWindow->setFrame(Rect(100, 0, 200, 100));
- mSecondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+ mSecondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp
index c368e79..d2a98df 100644
--- a/services/inputflinger/tests/InputFlingerService_test.cpp
+++ b/services/inputflinger/tests/InputFlingerService_test.cpp
@@ -28,9 +28,9 @@
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
+#include <gui/WindowInfo.h>
#include <input/Input.h>
#include <input/InputTransport.h>
-#include <input/InputWindow.h>
#include <gtest/gtest.h>
#include <inttypes.h>
@@ -44,6 +44,9 @@
#define TAG "InputFlingerServiceTest"
+using android::gui::FocusRequest;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
using android::os::BnInputFlinger;
using android::os::BnSetInputWindowsListener;
using android::os::IInputFlinger;
@@ -58,8 +61,8 @@
static const sp<IBinder> FocusedTestInfoToken = new BBinder();
static constexpr int32_t TestInfoId = 1;
static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo";
-static constexpr Flags<InputWindowInfo::Flag> TestInfoFlags = InputWindowInfo::Flag::NOT_FOCUSABLE;
-static constexpr InputWindowInfo::Type TestInfoType = InputWindowInfo::Type::INPUT_METHOD;
+static constexpr Flags<WindowInfo::Flag> TestInfoFlags = WindowInfo::Flag::NOT_FOCUSABLE;
+static constexpr WindowInfo::Type TestInfoType = WindowInfo::Type::INPUT_METHOD;
static constexpr std::chrono::duration TestInfoDispatchingTimeout = 2532ms;
static constexpr int32_t TestInfoFrameLeft = 93;
static constexpr int32_t TestInfoFrameTop = 34;
@@ -79,8 +82,7 @@
static constexpr bool TestInfoPaused = false;
static constexpr int32_t TestInfoOwnerPid = 19;
static constexpr int32_t TestInfoOwnerUid = 24;
-static constexpr InputWindowInfo::Feature TestInfoInputFeatures =
- InputWindowInfo::Feature::NO_INPUT_CHANNEL;
+static constexpr WindowInfo::Feature TestInfoInputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
static constexpr int32_t TestInfoDisplayId = 34;
static constexpr int32_t TestInfoPortalToDisplayId = 2;
static constexpr bool TestInfoReplaceTouchableRegionWithCrop = true;
@@ -102,13 +104,13 @@
protected:
void InitializeInputFlinger();
- void setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos);
+ void setInputWindowsByInfos(const std::vector<WindowInfo>& infos);
void setFocusedWindow(const sp<IBinder> token, const sp<IBinder> focusedToken,
nsecs_t timestampNanos);
void setInputWindowsFinished();
- void verifyInputWindowInfo(const InputWindowInfo& info) const;
- InputWindowInfo& getInfo() const { return const_cast<InputWindowInfo&>(mInfo); }
+ void verifyInputWindowInfo(const WindowInfo& info) const;
+ WindowInfo& getInfo() const { return const_cast<WindowInfo&>(mInfo); }
sp<IInputFlinger> mService;
sp<IInputFlingerQuery> mQuery;
@@ -116,7 +118,7 @@
private:
sp<SetInputWindowsListener> mSetInputWindowsListener;
std::unique_ptr<InputChannel> mServerChannel, mClientChannel;
- InputWindowInfo mInfo;
+ WindowInfo mInfo;
std::mutex mLock;
std::condition_variable mSetInputWindowsFinishedCondition;
};
@@ -136,14 +138,14 @@
public:
TestInputManager(){};
- binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles);
+ binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles);
binder::Status getInputChannels(std::vector<::android::InputChannel>* channels);
binder::Status getLastFocusRequest(FocusRequest*);
status_t dump(int fd, const Vector<String16>& args) override;
binder::Status setInputWindows(
- const std::vector<InputWindowInfo>& handles,
+ const std::vector<WindowInfo>& handles,
const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
@@ -154,7 +156,7 @@
private:
mutable Mutex mLock;
- std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mHandlesPerDisplay;
+ std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> mHandlesPerDisplay;
std::vector<std::shared_ptr<InputChannel>> mInputChannels;
FocusRequest mFocusRequest;
};
@@ -162,7 +164,7 @@
class TestInputQuery : public BnInputFlingerQuery {
public:
TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){};
- binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles) override;
+ binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles) override;
binder::Status getInputChannels(std::vector<::android::InputChannel>* channels) override;
binder::Status getLastFocusRequest(FocusRequest*) override;
binder::Status resetInputManager() override;
@@ -171,8 +173,7 @@
sp<android::TestInputManager> mManager;
};
-binder::Status TestInputQuery::getInputWindows(
- std::vector<::android::InputWindowInfo>* inputHandles) {
+binder::Status TestInputQuery::getInputWindows(std::vector<WindowInfo>* inputHandles) {
return mManager->getInputWindows(inputHandles);
}
@@ -197,13 +198,13 @@
}
binder::Status TestInputManager::setInputWindows(
- const std::vector<InputWindowInfo>& infos,
+ const std::vector<WindowInfo>& infos,
const sp<ISetInputWindowsListener>& setInputWindowsListener) {
AutoMutex _l(mLock);
for (const auto& info : infos) {
- mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
- mHandlesPerDisplay[info.displayId].push_back(new InputWindowHandle(info));
+ mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
+ mHandlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
}
if (setInputWindowsListener) {
setInputWindowsListener->onSetInputWindowsFinished();
@@ -248,8 +249,7 @@
return NO_ERROR;
}
-binder::Status TestInputManager::getInputWindows(
- std::vector<::android::InputWindowInfo>* inputInfos) {
+binder::Status TestInputManager::getInputWindows(std::vector<WindowInfo>* inputInfos) {
for (auto& [displayId, inputHandles] : mHandlesPerDisplay) {
for (auto& inputHandle : inputHandles) {
inputInfos->push_back(*inputHandle->getInfo());
@@ -331,7 +331,7 @@
mQuery->resetInputManager();
}
-void InputFlingerServiceTest::verifyInputWindowInfo(const InputWindowInfo& info) const {
+void InputFlingerServiceTest::verifyInputWindowInfo(const WindowInfo& info) const {
EXPECT_EQ(mInfo, info);
}
@@ -345,7 +345,7 @@
mQuery = interface_cast<IInputFlingerQuery>(input);
}
-void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos) {
+void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<WindowInfo>& infos) {
std::unique_lock<std::mutex> lock(mLock);
mService->setInputWindows(infos, mSetInputWindowsListener);
// Verify listener call
@@ -361,20 +361,20 @@
request.timestamp = timestampNanos;
mService->setFocusedWindow(request);
// call set input windows and wait for the callback to drain the queue.
- setInputWindowsByInfos(std::vector<InputWindowInfo>());
+ setInputWindowsByInfos(std::vector<WindowInfo>());
}
/**
* Test InputFlinger service interface SetInputWindows
*/
TEST_F(InputFlingerServiceTest, InputWindow_SetInputWindows) {
- std::vector<InputWindowInfo> infos = {getInfo()};
+ std::vector<WindowInfo> infos = {getInfo()};
setInputWindowsByInfos(infos);
// Verify input windows from service
- std::vector<::android::InputWindowInfo> windowInfos;
+ std::vector<WindowInfo> windowInfos;
mQuery->getInputWindows(&windowInfos);
- for (const ::android::InputWindowInfo& windowInfo : windowInfos) {
+ for (const WindowInfo& windowInfo : windowInfos) {
verifyInputWindowInfo(windowInfo);
}
}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 997cbe8..778f6e6 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -32,6 +32,7 @@
#include <VibratorInputMapper.h>
#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <inttypes.h>
#include <math.h>
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index e7e1937..89c0741 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -16,6 +16,7 @@
#include "../dispatcher/LatencyTracker.h"
+#include <android-base/properties.h>
#include <binder/Binder.h>
#include <gtest/gtest.h>
#include <inttypes.h>
@@ -23,11 +24,16 @@
#define TAG "LatencyTracker_test"
+using android::base::HwTimeoutMultiplier;
using android::inputdispatcher::InputEventTimeline;
using android::inputdispatcher::LatencyTracker;
namespace android::inputdispatcher {
+const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds(
+ android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
+ HwTimeoutMultiplier());
+
InputEventTimeline getTestTimeline() {
InputEventTimeline t(
/*isDown*/ true,
@@ -57,6 +63,8 @@
}
void TearDown() override {}
+ void triggerEventReporting(nsecs_t lastEventTime);
+
void assertReceivedTimeline(const InputEventTimeline& timeline);
/**
* Timelines can be received in any order (order is not guaranteed). So if we are expecting more
@@ -72,8 +80,17 @@
std::deque<InputEventTimeline> mReceivedTimelines;
};
+/**
+ * Send an event that would trigger the reporting of all of the events that are at least as old as
+ * the provided 'lastEventTime'.
+ */
+void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) {
+ const nsecs_t triggerEventTime =
+ lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
+ mTracker->trackListener(1 /*inputEventId*/, true /*isDown*/, triggerEventTime, 3 /*readTime*/);
+}
+
void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) {
- mTracker->reportNow();
ASSERT_FALSE(mReceivedTimelines.empty());
const InputEventTimeline& t = mReceivedTimelines.front();
ASSERT_EQ(timeline, t);
@@ -88,7 +105,6 @@
* equal element in B, and for every element in B there is an equal element in A.
*/
void LatencyTrackerTest::assertReceivedTimelines(const std::vector<InputEventTimeline>& timelines) {
- mTracker->reportNow();
ASSERT_EQ(timelines.size(), mReceivedTimelines.size());
for (const InputEventTimeline& expectedTimeline : timelines) {
bool found = false;
@@ -121,6 +137,7 @@
*/
TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
mTracker->trackListener(1 /*inputEventId*/, false /*isDown*/, 2 /*eventTime*/, 3 /*readTime*/);
+ triggerEventReporting(2 /*eventTime*/);
assertReceivedTimeline(InputEventTimeline{false, 2, 3});
}
@@ -130,6 +147,7 @@
TEST_F(LatencyTrackerTest, TrackFinishedEvent_DoesNotTriggerReporting) {
mTracker->trackFinishedEvent(1 /*inputEventId*/, connection1, 2 /*deliveryTime*/,
3 /*consumeTime*/, 4 /*finishTime*/);
+ triggerEventReporting(4 /*eventTime*/);
assertReceivedTimelines({});
}
@@ -141,6 +159,7 @@
graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 2;
graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 3;
mTracker->trackGraphicsLatency(1 /*inputEventId*/, connection2, graphicsTimeline);
+ triggerEventReporting(3 /*eventTime*/);
assertReceivedTimelines({});
}
@@ -155,9 +174,30 @@
expectedCT.consumeTime, expectedCT.finishTime);
mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
+ triggerEventReporting(expected.eventTime);
assertReceivedTimeline(expected);
}
+/**
+ * Send 2 events with the same inputEventId, but different eventTime's. Ensure that no crash occurs,
+ * and that the tracker drops such events completely.
+ */
+TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) {
+ constexpr nsecs_t inputEventId = 1;
+ constexpr nsecs_t readTime = 3; // does not matter for this test
+ constexpr bool isDown = true; // does not matter for this test
+
+ // In the following 2 calls to trackListener, the inputEventId's are the same, but event times
+ // are different.
+ mTracker->trackListener(inputEventId, isDown, 1 /*eventTime*/, readTime);
+ mTracker->trackListener(inputEventId, isDown, 2 /*eventTime*/, readTime);
+
+ triggerEventReporting(2 /*eventTime*/);
+ // Since we sent duplicate input events, the tracker should just delete all of them, because it
+ // does not have enough information to properly track them.
+ assertReceivedTimelines({});
+}
+
TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) {
constexpr int32_t inputEventId1 = 1;
InputEventTimeline timeline1(
@@ -204,6 +244,7 @@
mTracker->trackGraphicsLatency(inputEventId2, connection2,
connectionTimeline2.graphicsTimeline);
// Now both events should be completed
+ triggerEventReporting(timeline2.eventTime);
assertReceivedTimelines({timeline1, timeline2});
}
@@ -228,6 +269,7 @@
mTracker->trackGraphicsLatency(1 /*inputEventId*/, token, expectedCT.graphicsTimeline);
expectedTimelines[0].connectionTimelines.emplace(token, std::move(expectedCT));
+ triggerEventReporting(timeline.eventTime);
assertReceivedTimelines(expectedTimelines);
}
@@ -246,6 +288,7 @@
mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime);
+ triggerEventReporting(expected.eventTime);
assertReceivedTimeline(
InputEventTimeline{expected.isDown, expected.eventTime, expected.readTime});
}
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
new file mode 100644
index 0000000..df4db19
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -0,0 +1,45 @@
+// 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_fuzz {
+ name: "inputflinger_latencytracker_fuzzer",
+ defaults: [
+ "inputflinger_defaults",
+ ],
+ include_dirs: [
+ "frameworks/native/services/inputflinger",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libui",
+ "libutils",
+ "libinput",
+ "libinputflinger",
+ ],
+ srcs: [
+ "LatencyTrackerFuzzer.cpp",
+ ],
+}
diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
new file mode 100644
index 0000000..4f066ad
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 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 <fuzzer/FuzzedDataProvider.h>
+#include "dispatcher/LatencyTracker.h"
+
+namespace android {
+
+namespace inputdispatcher {
+
+/**
+ * A processor of InputEventTimelines that does nothing with the provided data.
+ */
+class EmptyProcessor : public InputEventTimelineProcessor {
+public:
+ /**
+ * Just ignore the provided timeline
+ */
+ void processTimeline(const InputEventTimeline& timeline) override {
+ for (const auto& [token, connectionTimeline] : timeline.connectionTimelines) {
+ connectionTimeline.isComplete();
+ }
+ };
+};
+
+static sp<IBinder> getConnectionToken(FuzzedDataProvider& fdp,
+ std::array<sp<IBinder>, 10>& tokens) {
+ const bool useExistingToken = fdp.ConsumeBool();
+ if (useExistingToken) {
+ return tokens[fdp.ConsumeIntegralInRange<size_t>(0ul, tokens.size() - 1)];
+ }
+ return new BBinder();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+
+ EmptyProcessor emptyProcessor;
+ LatencyTracker tracker(&emptyProcessor);
+
+ // Make some pre-defined tokens to ensure that some timelines are complete.
+ std::array<sp<IBinder> /*token*/, 10> predefinedTokens;
+ for (size_t i = 0; i < predefinedTokens.size(); i++) {
+ predefinedTokens[i] = new BBinder();
+ }
+
+ // Randomly invoke LatencyTracker api's until randomness is exhausted.
+ while (fdp.remaining_bytes() > 0) {
+ fdp.PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ int32_t isDown = fdp.ConsumeBool();
+ nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
+ nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
+ tracker.trackListener(inputEventId, isDown, eventTime, readTime);
+ },
+ [&]() -> void {
+ int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
+ nsecs_t deliveryTime = fdp.ConsumeIntegral<nsecs_t>();
+ nsecs_t consumeTime = fdp.ConsumeIntegral<nsecs_t>();
+ nsecs_t finishTime = fdp.ConsumeIntegral<nsecs_t>();
+ tracker.trackFinishedEvent(inputEventId, connectionToken, deliveryTime,
+ consumeTime, finishTime);
+ },
+ [&]() -> void {
+ int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+ sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
+ std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
+ for (size_t i = 0; i < graphicsTimeline.size(); i++) {
+ graphicsTimeline[i] = fdp.ConsumeIntegral<nsecs_t>();
+ }
+ tracker.trackGraphicsLatency(inputEventId, connectionToken, graphicsTimeline);
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace inputdispatcher
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index e669e45..34b8281 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -146,6 +146,7 @@
"DisplayHardware/ComposerHal.cpp",
"DisplayHardware/DisplayIdentification.cpp",
"DisplayHardware/FramebufferSurface.cpp",
+ "DisplayHardware/Hash.cpp",
"DisplayHardware/HWC2.cpp",
"DisplayHardware/HWComposer.cpp",
"DisplayHardware/PowerAdvisor.cpp",
@@ -211,7 +212,6 @@
"libcutils",
"libdisplayservicehidl",
"libhidlbase",
- "libinput",
"liblayers_proto",
"liblog",
"libprocessgroup",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 23779be..b600fad 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -58,6 +58,8 @@
namespace android {
+using gui::WindowInfo;
+
static constexpr float defaultMaxLuminance = 1000.0;
BufferLayer::BufferLayer(const LayerCreationArgs& args)
@@ -150,39 +152,10 @@
return result;
}
- if (CC_UNLIKELY(mBufferInfo.mBuffer == 0)) {
- // the texture has not been created yet, this Layer has
- // in fact never been drawn into. This happens frequently with
- // SurfaceView because the WindowManager can't know when the client
- // has drawn the first time.
-
- // If there is nothing under us, we paint the screen in black, otherwise
- // we just skip this update.
-
- // figure out if there is something below us
- Region under;
- bool finished = false;
- mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
- if (finished || layer == static_cast<BufferLayer const*>(this)) {
- finished = true;
- return;
- }
-
- under.orSelf(layer->getScreenBounds());
- });
- // if not everything below us is covered, we plug the holes!
- Region holes(targetSettings.clip.subtract(under));
- if (!holes.isEmpty()) {
- targetSettings.clearRegion.orSelf(holes);
- }
-
- if (mSidebandStream != nullptr) {
- // For surfaceview of tv sideband, there is no activeBuffer
- // in bufferqueue, we need return LayerSettings.
- return result;
- } else {
- return std::nullopt;
- }
+ if (CC_UNLIKELY(mBufferInfo.mBuffer == 0) && mSidebandStream != nullptr) {
+ // For surfaceview of tv sideband, there is no activeBuffer
+ // in bufferqueue, we need return LayerSettings.
+ return result;
}
const bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) ||
((isSecure() || isProtected()) && !targetSettings.isSecure);
@@ -419,33 +392,35 @@
mFrameTracker.setFrameReadyTime(desiredPresentTime);
}
- const Fps refreshRate = mFlinger->mRefreshRateConfigs->getCurrentRefreshRate().getFps();
- const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
- if (presentFence->isValid()) {
- mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
- refreshRate, renderRate,
- frameRateToSetFrameRateVotePayload(
- mDrawingState.frameRate),
- getGameMode());
- mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
- presentFence, FrameTracer::FrameEvent::PRESENT_FENCE);
- mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
- } else if (!display) {
- // Do nothing.
- } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
- displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
- // The HWC doesn't support present fences, so use the refresh
- // timestamp instead.
- const nsecs_t actualPresentTime = display->getRefreshTimestamp();
- mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
- refreshRate, renderRate,
- frameRateToSetFrameRateVotePayload(
- mDrawingState.frameRate),
- getGameMode());
- mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
- actualPresentTime,
+ if (display) {
+ const Fps refreshRate = display->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ const std::optional<Fps> renderRate =
+ mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
+ if (presentFence->isValid()) {
+ mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
+ refreshRate, renderRate,
+ frameRateToSetFrameRateVotePayload(
+ mDrawingState.frameRate),
+ getGameMode());
+ mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
+ presentFence,
FrameTracer::FrameEvent::PRESENT_FENCE);
- mFrameTracker.setActualPresentTime(actualPresentTime);
+ mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
+ } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+ displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
+ // The HWC doesn't support present fences, so use the refresh
+ // timestamp instead.
+ const nsecs_t actualPresentTime = display->getRefreshTimestamp();
+ mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
+ refreshRate, renderRate,
+ frameRateToSetFrameRateVotePayload(
+ mDrawingState.frameRate),
+ getGameMode());
+ mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(),
+ mCurrentFrameNumber, actualPresentTime,
+ FrameTracer::FrameEvent::PRESENT_FENCE);
+ mFrameTracker.setActualPresentTime(actualPresentTime);
+ }
}
mFrameTracker.advanceFrame();
@@ -825,7 +800,7 @@
wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf;
SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives;
wp<Layer> tmpTouchableRegionCrop = mDrawingState.touchableRegionCrop;
- InputWindowInfo tmpInputInfo = mDrawingState.inputInfo;
+ WindowInfo tmpInputInfo = mDrawingState.inputInfo;
mDrawingState = clonedFrom->mDrawingState;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 6b6d434..81254ac 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -153,11 +153,12 @@
}
bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
+ Mutex::Autolock lock(mQueueItemLock);
+
if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
return true;
}
- Mutex::Autolock lock(mQueueItemLock);
return mQueueItems[0].item.mTimestamp <= expectedPresentTime;
}
@@ -269,13 +270,15 @@
// and return early
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
- mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
- mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
- if (mQueueItems[0].surfaceFrame) {
- addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+ if (mQueuedFrames > 0) {
+ mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
+ mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
+ if (mQueueItems[0].surfaceFrame) {
+ addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+ }
+ mQueueItems.erase(mQueueItems.begin());
+ mQueuedFrames--;
}
- mQueueItems.erase(mQueueItems.begin());
- mQueuedFrames--;
}
return BAD_VALUE;
} else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
@@ -305,6 +308,7 @@
return BAD_VALUE;
}
+ bool more_frames_pending = false;
if (queuedBuffer) {
// Autolock scope
auto currentFrameNumber = mConsumer->getFrameNumber();
@@ -313,7 +317,7 @@
// Remove any stale buffers that have been dropped during
// updateTexImage
- while (mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
+ while (mQueuedFrames > 0 && mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
if (mQueueItems[0].surfaceFrame) {
@@ -334,11 +338,12 @@
latchTime);
}
mQueueItems.erase(mQueueItems.begin());
+ more_frames_pending = (mQueuedFrames.fetch_sub(1) > 1);
}
// Decrement the queued-frames count. Signal another event if we
// have more frames pending.
- if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
+ if ((queuedBuffer && more_frames_pending) || mAutoRefresh) {
mFlinger->signalLayerUpdate();
}
@@ -515,13 +520,10 @@
}
status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) {
- uint32_t const maxSurfaceDims =
- std::min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
-
// never allow a surface larger than what our underlying GL implementation
// can handle.
- if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
- ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
+ if (mFlinger->exceedsMaxRenderTargetSize(w, h)) {
+ ALOGE("dimensions too large %" PRIu32 " x %" PRIu32, w, h);
return BAD_VALUE;
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 14eddb1..526e7da 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -40,7 +40,7 @@
std::optional<ui::DisplayConnectionType> connectionType;
// Size of the display in pixels
- ui::Size pixels = ui::Size::INVALID;
+ ui::Size pixels = ui::kInvalidSize;
// True if this display should be considered secure
bool isSecure = false;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index e51019a..6d1017f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -115,10 +115,6 @@
// If set to true, the target buffer has protected content support.
const bool supportsProtectedContent;
- // Modified by each call to prepareClientComposition to indicate the
- // region of the target buffer that should be cleared.
- Region& clearRegion;
-
// Viewport of the target being rendered to. This is used to determine
// the shadow light position.
const Rect& viewport;
@@ -177,11 +173,10 @@
static inline bool operator==(const LayerFE::ClientCompositionTargetSettings& lhs,
const LayerFE::ClientCompositionTargetSettings& rhs) {
- return lhs.clip.hasSameRects(rhs.clip) &&
- lhs.needsFiltering == rhs.needsFiltering && lhs.isSecure == rhs.isSecure &&
+ return lhs.clip.hasSameRects(rhs.clip) && lhs.needsFiltering == rhs.needsFiltering &&
+ lhs.isSecure == rhs.isSecure &&
lhs.supportsProtectedContent == rhs.supportsProtectedContent &&
- lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.viewport == rhs.viewport &&
- lhs.dataspace == rhs.dataspace &&
+ lhs.viewport == rhs.viewport && lhs.dataspace == rhs.dataspace &&
lhs.realContentIsVisible == rhs.realContentIsVisible &&
lhs.clearContent == rhs.clearContent;
}
@@ -202,8 +197,6 @@
*os << "\n .needsFiltering = " << settings.needsFiltering;
*os << "\n .isSecure = " << settings.isSecure;
*os << "\n .supportsProtectedContent = " << settings.supportsProtectedContent;
- *os << "\n .clearRegion = ";
- PrintTo(settings.clearRegion, os);
*os << "\n .viewport = ";
PrintTo(settings.viewport, os);
*os << "\n .dataspace = ";
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 1416b1e..15a86af 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -166,6 +166,9 @@
// Enables (or disables) layer caching on this output
virtual void setLayerCachingEnabled(bool) = 0;
+ // Enables (or disables) layer caching texture pool on this output
+ virtual void setLayerCachingTexturePoolEnabled(bool) = 0;
+
// Sets the projection state to use
virtual void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
const Rect& orientedDisplaySpaceRect) = 0;
@@ -291,7 +294,7 @@
virtual bool getSkipColorTransform() const = 0;
virtual FrameFences presentAndGetFrameFences() = 0;
virtual std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
- bool supportsProtectedContent, Region& clearRegion, ui::Dataspace outputDataspace) = 0;
+ bool supportsProtectedContent, ui::Dataspace outputDataspace) = 0;
virtual void appendRegionFlashRequests(
const Region& flashRegion,
std::vector<LayerFE::LayerSettings>& clientCompositionLayers) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index f832084..14f2163 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -41,6 +41,7 @@
std::optional<DisplayId> getDisplayId() const override;
void setCompositionEnabled(bool) override;
void setLayerCachingEnabled(bool) override;
+ void setLayerCachingTexturePoolEnabled(bool) override;
void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
const Rect& orientedDisplaySpaceRect) override;
void setDisplaySize(const ui::Size&) override;
@@ -110,8 +111,7 @@
bool getSkipColorTransform() const override;
compositionengine::Output::FrameFences presentAndGetFrameFences() override;
std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
- bool supportsProtectedContent, Region& clearRegion,
- ui::Dataspace outputDataspace) override;
+ bool supportsProtectedContent, ui::Dataspace outputDataspace) override;
void appendRegionFlashRequests(const Region&, std::vector<LayerFE::LayerSettings>&) override;
void setExpensiveRenderingExpected(bool enabled) override;
void dumpBase(std::string&) const;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
index 7534548..8ec15ed 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
@@ -80,6 +80,8 @@
void renderCachedSets(const OutputCompositionState& outputState,
std::optional<std::chrono::steady_clock::time_point> renderDeadline);
+ void setTexturePoolEnabled(bool enabled) { mTexturePool.setEnabled(enabled); }
+
void dump(std::string& result) const;
void dumpLayers(std::string& result) const;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index bce438f..5237527 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -21,7 +21,7 @@
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
-#include <input/Flags.h>
+#include <ftl/Flags.h>
#include <string>
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
index be34153..76d5e81 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
@@ -64,6 +64,8 @@
void renderCachedSets(const OutputCompositionState& outputState,
std::optional<std::chrono::steady_clock::time_point> renderDeadline);
+ void setTexturePoolEnabled(bool enabled) { mFlattener.setTexturePoolEnabled(enabled); }
+
void dump(const Vector<String16>& args, std::string&);
private:
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
index fb53ee0..d607c75 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
@@ -63,7 +63,8 @@
sp<Fence> mFence;
};
- TexturePool(renderengine::RenderEngine& renderEngine) : mRenderEngine(renderEngine) {}
+ TexturePool(renderengine::RenderEngine& renderEngine)
+ : mRenderEngine(renderEngine), mEnabled(false) {}
virtual ~TexturePool() = default;
@@ -78,6 +79,12 @@
// to the pool.
std::shared_ptr<AutoTexture> borrowTexture();
+ // Enables or disables the pool. When the pool is disabled, no buffers will
+ // be held by the pool. This is useful when the active display changes.
+ void setEnabled(bool enable);
+
+ void dump(std::string& out) const;
+
protected:
// Proteted visibility so that they can be used for testing
const static constexpr size_t kMinPoolSize = 3;
@@ -95,8 +102,10 @@
// Returns a previously borrowed texture to the pool.
void returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture,
const sp<Fence>& fence);
+ void allocatePool();
renderengine::RenderEngine& mRenderEngine;
ui::Size mSize;
+ bool mEnabled;
};
} // namespace android::compositionengine::impl::planner
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 8e777e3..216019f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -37,6 +37,7 @@
MOCK_METHOD1(setCompositionEnabled, void(bool));
MOCK_METHOD1(setLayerCachingEnabled, void(bool));
+ MOCK_METHOD1(setLayerCachingTexturePoolEnabled, void(bool));
MOCK_METHOD3(setProjection, void(ui::Rotation, const Rect&, const Rect&));
MOCK_METHOD1(setDisplaySize, void(const ui::Size&));
MOCK_METHOD2(setLayerStackFilter, void(uint32_t, bool));
@@ -112,8 +113,8 @@
MOCK_METHOD1(renderCachedSets, void(const CompositionRefreshArgs&));
MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
- MOCK_METHOD3(generateClientCompositionRequests,
- std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
+ MOCK_METHOD2(generateClientCompositionRequests,
+ std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
MOCK_METHOD2(appendRegionFlashRequests,
void(const Region&, std::vector<LayerFE::LayerSettings>&));
MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index cafcb40..6ac488b 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -146,6 +146,12 @@
}
}
+void Output::setLayerCachingTexturePoolEnabled(bool enabled) {
+ if (mPlanner) {
+ mPlanner->setTexturePoolEnabled(enabled);
+ }
+}
+
void Output::setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
const Rect& orientedDisplaySpaceRect) {
auto& outputState = editState();
@@ -1069,13 +1075,9 @@
clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
}
- // Note: Updated by generateClientCompositionRequests
- clientCompositionDisplay.clearRegion = Region::INVALID_REGION;
-
// Generate the client composition requests for the layers on this output.
std::vector<LayerFE::LayerSettings> clientCompositionLayers =
generateClientCompositionRequests(supportsProtectedContent,
- clientCompositionDisplay.clearRegion,
clientCompositionDisplay.outputDataspace);
appendRegionFlashRequests(debugRegion, clientCompositionLayers);
@@ -1143,15 +1145,13 @@
}
std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
- bool supportsProtectedContent, Region& clearRegion, ui::Dataspace outputDataspace) {
+ bool supportsProtectedContent, ui::Dataspace outputDataspace) {
std::vector<LayerFE::LayerSettings> clientCompositionLayers;
ALOGV("Rendering client layers");
const auto& outputState = getState();
const Region viewportRegion(outputState.layerStackSpace.content);
bool firstLayer = true;
- // Used when a layer clears part of the buffer.
- Region stubRegion;
bool disableBlurs = false;
sp<GraphicBuffer> previousOverrideBuffer = nullptr;
@@ -1213,7 +1213,6 @@
outputState.needsFiltering,
.isSecure = outputState.isSecure,
.supportsProtectedContent = supportsProtectedContent,
- .clearRegion = clientComposition ? clearRegion : stubRegion,
.viewport = outputState.layerStackSpace.content,
.dataspace = outputDataspace,
.realContentIsVisible = realContentIsVisible,
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index f80ec22..56bb39a 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -171,13 +171,11 @@
.orientation = orientation,
};
- Region clearRegion = Region::INVALID_REGION;
LayerFE::ClientCompositionTargetSettings targetSettings{
.clip = Region(viewport),
.needsFiltering = false,
.isSecure = outputState.isSecure,
.supportsProtectedContent = false,
- .clearRegion = clearRegion,
.viewport = viewport,
.dataspace = outputDataspace,
.realContentIsVisible = true,
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
index f033279..8e2c182 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
@@ -205,6 +205,9 @@
durationString(lastUpdate).c_str());
dumpLayers(result);
+
+ base::StringAppendF(&result, "\n");
+ mTexturePool.dump(result);
}
size_t Flattener::calculateDisplayCost(const std::vector<const LayerState*>& layers) const {
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
index e3772a2..497c433 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
@@ -24,14 +24,22 @@
namespace android::compositionengine::impl::planner {
+void TexturePool::allocatePool() {
+ mPool.clear();
+ if (mEnabled && mSize.isValid()) {
+ mPool.resize(kMinPoolSize);
+ std::generate_n(mPool.begin(), kMinPoolSize, [&]() {
+ return Entry{genTexture(), nullptr};
+ });
+ }
+}
+
void TexturePool::setDisplaySize(ui::Size size) {
if (mSize == size) {
return;
}
mSize = size;
- mPool.clear();
- mPool.resize(kMinPoolSize);
- std::generate_n(mPool.begin(), kMinPoolSize, [&]() { return Entry{genTexture(), nullptr}; });
+ allocatePool();
}
std::shared_ptr<TexturePool::AutoTexture> TexturePool::borrowTexture() {
@@ -46,7 +54,12 @@
void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture,
const sp<Fence>& fence) {
- // Drop the texture on the floor if the pool is no longer tracking textures of the same size.
+ // Drop the texture on the floor if the pool is not enabled
+ if (!mEnabled) {
+ return;
+ }
+
+ // Or the texture on the floor if the pool is no longer tracking textures of the same size.
if (static_cast<int32_t>(texture->getBuffer()->getWidth()) != mSize.getWidth() ||
static_cast<int32_t>(texture->getBuffer()->getHeight()) != mSize.getHeight()) {
ALOGV("Deallocating texture from Planner's pool - display size changed (previous: (%dx%d), "
@@ -81,4 +94,15 @@
renderengine::ExternalTexture::Usage::WRITEABLE);
}
+void TexturePool::setEnabled(bool enabled) {
+ mEnabled = enabled;
+ allocatePool();
+}
+
+void TexturePool::dump(std::string& out) const {
+ base::StringAppendF(&out,
+ "TexturePool (%s) has %zu buffers of size [%" PRId32 ", %" PRId32 "]\n",
+ mEnabled ? "enabled" : "disabled", mPool.size(), mSize.width, mSize.height);
+}
+
} // namespace android::compositionengine::impl::planner
\ No newline at end of file
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index c037cc6..72b16e0 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -60,7 +60,7 @@
constexpr HalVirtualDisplayId HAL_VIRTUAL_DISPLAY_ID{456u};
constexpr GpuVirtualDisplayId GPU_VIRTUAL_DISPLAY_ID{789u};
-const ui::Size DEFAULT_RESOLUTION{1920, 1080};
+constexpr ui::Size DEFAULT_RESOLUTION{1920, 1080};
constexpr uint32_t DEFAULT_LAYER_STACK = 42;
struct Layer {
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index a195e58..65c97b7 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -51,6 +51,7 @@
bool(HalVirtualDisplayId, ui::Size, ui::PixelFormat*,
std::optional<PhysicalDisplayId>));
MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
+
MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId));
MOCK_METHOD5(getDeviceCompositionChanges,
status_t(HalDisplayId, bool, std::chrono::steady_clock::time_point,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index ee73cfc..c3185e9 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -2992,8 +2992,8 @@
// Sets up the helper functions called by the function under test to use
// mock implementations.
MOCK_CONST_METHOD0(getSkipColorTransform, bool());
- MOCK_METHOD3(generateClientCompositionRequests,
- std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
+ MOCK_METHOD2(generateClientCompositionRequests,
+ std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
MOCK_METHOD2(appendRegionFlashRequests,
void(const Region&, std::vector<LayerFE::LayerSettings>&));
MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
@@ -3142,7 +3142,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3165,7 +3165,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(
@@ -3195,7 +3195,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(
@@ -3223,7 +3223,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3252,7 +3252,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3281,7 +3281,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3316,7 +3316,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
@@ -3339,7 +3339,7 @@
OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3391,7 +3391,7 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- Region::INVALID_REGION, kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags})
.execute()
.expectAFenceWasReturned();
}
@@ -3402,7 +3402,7 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- Region::INVALID_REGION, kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags})
.execute()
.expectAFenceWasReturned();
}
@@ -3413,7 +3413,7 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace,
- kDefaultColorTransformMat, Region::INVALID_REGION,
+ kDefaultColorTransformMat,
kDefaultOutputOrientationFlags})
.execute()
.expectAFenceWasReturned();
@@ -3425,7 +3425,7 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace,
- kDefaultColorTransformMat, Region::INVALID_REGION,
+ kDefaultColorTransformMat,
kDefaultOutputOrientationFlags})
.execute()
.expectAFenceWasReturned();
@@ -3438,7 +3438,7 @@
.andIfSkipColorTransform(true)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- Region::INVALID_REGION, kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags})
.execute()
.expectAFenceWasReturned();
}
@@ -3469,7 +3469,7 @@
EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _))
.WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
@@ -3590,7 +3590,7 @@
TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
mOutput.mState.dataspace = kExpensiveOutputDataspace;
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
// For this test, we also check the call order of key functions.
@@ -3612,7 +3612,7 @@
EXPECT_CALL(mLayer.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
@@ -3652,10 +3652,9 @@
struct OutputPartialMock : public OutputPartialMockBase {
// compositionengine::Output overrides
std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
- bool supportsProtectedContent, Region& clearRegion,
- ui::Dataspace dataspace) override {
+ bool supportsProtectedContent, ui::Dataspace dataspace) override {
return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
- clearRegion, dataspace);
+ dataspace);
}
};
@@ -3739,11 +3738,9 @@
EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
EXPECT_EQ(0u, requests.size());
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
@@ -3751,11 +3748,9 @@
mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
EXPECT_EQ(0u, requests.size());
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
@@ -3770,16 +3765,13 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>(
{mShadowSettings, mLayers[2].mLayerSettings})));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(3u, requests.size());
EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
EXPECT_EQ(mShadowSettings, requests[1]);
EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
-
// Check that a timestamp was set for the layers that generated requests
EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
@@ -3810,16 +3802,13 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>(
{mShadowSettings, mLayers[2].mLayerSettings})));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(3u, requests.size());
EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
EXPECT_EQ(mShadowSettings, requests[1]);
EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
-
// Check that a timestamp was set for the layers that generated requests
EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
@@ -3843,13 +3832,10 @@
EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(1u, requests.size());
EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
-
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
@@ -3869,13 +3855,10 @@
EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
.WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
- Region accumClearRegion(Rect(10, 11, 12, 13));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(1u, requests.size());
EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
-
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
@@ -3896,15 +3879,12 @@
mLayers[0].mLayerFEState.isOpaque = true;
mLayers[1].mLayerFEState.isOpaque = true;
mLayers[2].mLayerFEState.isOpaque = true;
- Region accumClearRegion(Rect(10, 11, 12, 13));
- Region stubRegion;
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- stubRegion, /* clear region */
kDisplayViewport,
kDisplayDataspace,
false /* realContentIsVisible */,
@@ -3916,7 +3896,6 @@
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -3936,15 +3915,13 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(2u, requests.size());
// The second layer is expected to be rendered as alpha=0 black with no blending
EXPECT_EQ(mBlackoutSettings, requests[0]);
EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
-
- EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
@@ -3953,14 +3930,11 @@
mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
- Region accumClearRegion(Rect(10, 11, 12, 13));
-
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(Rect(10, 10, 20, 20)),
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -3972,7 +3946,6 @@
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -3984,7 +3957,6 @@
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4001,7 +3973,7 @@
static_cast<void>(
mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace));
+ kDisplayDataspace));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
@@ -4009,14 +3981,11 @@
mOutput.mState.needsFiltering = false;
EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
- Region accumClearRegion(Rect(10, 11, 12, 13));
-
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(kDisplayFrame),
true, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4028,7 +3997,6 @@
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4040,7 +4008,6 @@
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4057,7 +4024,7 @@
static_cast<void>(
mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace));
+ kDisplayDataspace));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
@@ -4065,14 +4032,11 @@
mOutput.mState.needsFiltering = true;
EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
- Region accumClearRegion(Rect(10, 11, 12, 13));
-
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(kDisplayFrame),
true, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4085,7 +4049,6 @@
true, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4097,7 +4060,6 @@
true, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4114,21 +4076,18 @@
static_cast<void>(
mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace));
+ kDisplayDataspace));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
wholeOutputSecurityUsedToGenerateRequests) {
mOutput.mState.isSecure = true;
- Region accumClearRegion(Rect(10, 11, 12, 13));
-
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(kDisplayFrame),
false, /* needs filtering */
true, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4140,7 +4099,6 @@
false, /* needs filtering */
true, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4152,7 +4110,6 @@
false, /* needs filtering */
true, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4169,19 +4126,17 @@
static_cast<void>(
mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace));
+ kDisplayDataspace));
}
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
protectedContentSupportUsedToGenerateRequests) {
- Region accumClearRegion(Rect(10, 11, 12, 13));
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(kDisplayFrame),
false, /* needs filtering */
false, /* secure */
true, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4193,7 +4148,6 @@
false, /* needs filtering */
false, /* secure */
true, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4205,7 +4159,6 @@
false, /* needs filtering */
false, /* secure */
true, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4221,7 +4174,6 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
- accumClearRegion,
kDisplayDataspace));
}
@@ -4336,14 +4288,11 @@
EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
.WillRepeatedly(Return(&rightLayer.mOutputLayer));
- Region accumClearRegion(Rect(10, 11, 12, 13));
-
compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
Region(Rect(0, 0, 1000, 1000)),
false, /* needs filtering */
true, /* secure */
true, /* supports protected content */
- accumClearRegion,
kPortraitViewport,
kOutputDataspace,
true /* realContentIsVisible */,
@@ -4361,7 +4310,6 @@
false, /* needs filtering */
true, /* secure */
true, /* supports protected content */
- accumClearRegion,
kPortraitViewport,
kOutputDataspace,
true /* realContentIsVisible */,
@@ -4375,8 +4323,8 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
constexpr bool supportsProtectedContent = true;
- auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
- accumClearRegion, kOutputDataspace);
+ auto requests =
+ mOutput.generateClientCompositionRequests(supportsProtectedContent, kOutputDataspace);
ASSERT_EQ(2u, requests.size());
EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
@@ -4389,13 +4337,11 @@
const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
- Region accumClearRegion(Rect(10, 11, 12, 13));
compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
false /* realContentIsVisible */,
@@ -4415,7 +4361,7 @@
.WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(1u, requests.size());
EXPECT_EQ(mShadowSettings, requests[0]);
@@ -4435,13 +4381,11 @@
mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
- Region accumClearRegion(Rect(10, 11, 12, 13));
compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
false, /* needs filtering */
false, /* secure */
false, /* supports protected content */
- accumClearRegion,
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4456,7 +4400,7 @@
{mShadowSettings, mLayers[2].mLayerSettings})));
auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
- accumClearRegion, kDisplayDataspace);
+ kDisplayDataspace);
ASSERT_EQ(2u, requests.size());
EXPECT_EQ(mShadowSettings, requests[0]);
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 5090bb2..431cc93 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -35,7 +35,7 @@
constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
-constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId(123u);
+constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(123u);
const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
using testing::_;
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
index b802e51..6fc90fe 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
@@ -42,6 +42,7 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+ mTexturePool.setEnabled(true);
mTexturePool.setDisplaySize(kDisplaySize);
}
@@ -130,5 +131,44 @@
static_cast<int32_t>(texture->get()->getBuffer()->getHeight()));
}
+TEST_F(TexturePoolTest, freesBuffersWhenDisabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
+
+ std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
+ for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
+ textures.emplace_back(mTexturePool.borrowTexture());
+ }
+
+ EXPECT_EQ(mTexturePool.getPoolSize(), 1u);
+ mTexturePool.setEnabled(false);
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+
+ textures.clear();
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+}
+
+TEST_F(TexturePoolTest, doesNotHoldBuffersWhenDisabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
+ mTexturePool.setEnabled(false);
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+
+ std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
+ for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
+ textures.emplace_back(mTexturePool.borrowTexture());
+ }
+
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+ textures.clear();
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+}
+
+TEST_F(TexturePoolTest, reallocatesWhenReEnabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
+ mTexturePool.setEnabled(false);
+ EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+ mTexturePool.setEnabled(true);
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
+}
+
} // namespace
} // namespace android::compositionengine::impl::planner
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index ca4b6ab..4445eea 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -22,6 +22,8 @@
#undef LOG_TAG
#define LOG_TAG "DisplayDevice"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/Display.h>
@@ -40,6 +42,7 @@
#include "DisplayDevice.h"
#include "Layer.h"
+#include "RefreshRateOverlay.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -65,9 +68,12 @@
mSequenceId(args.sequenceId),
mConnectionType(args.connectionType),
mCompositionDisplay{args.compositionDisplay},
+ mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())),
+ mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())),
mPhysicalOrientation(args.physicalOrientation),
mSupportedModes(std::move(args.supportedModes)),
- mIsPrimary(args.isPrimary) {
+ mIsPrimary(args.isPrimary),
+ mRefreshRateConfigs(std::move(args.refreshRateConfigs)) {
mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
compositionengine::RenderSurfaceCreationArgsBuilder()
@@ -154,20 +160,29 @@
void DisplayDevice::setActiveMode(DisplayModeId id) {
const auto mode = getMode(id);
LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported.");
+ ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue());
mActiveMode = mode;
+ if (mRefreshRateConfigs) {
+ mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
+ }
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
+ }
}
-status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
+status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info,
const hal::VsyncPeriodChangeConstraints& constraints,
- hal::VsyncPeriodChangeTimeline* outTimeline) const {
- const auto mode = getMode(modeId);
- if (!mode) {
+ hal::VsyncPeriodChangeTimeline* outTimeline) {
+ if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) {
ALOGE("Trying to initiate a mode change to invalid mode %s on display %s",
- std::to_string(modeId.value()).c_str(), to_string(getId()).c_str());
+ info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null",
+ to_string(getId()).c_str());
return BAD_VALUE;
}
- return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints,
- outTimeline);
+ mUpcomingActiveMode = info;
+ ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue());
+ return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(),
+ constraints, outTimeline);
}
const DisplayModePtr& DisplayDevice::getActiveMode() const {
@@ -217,12 +232,23 @@
}
void DisplayDevice::setLayerStack(ui::LayerStack stack) {
- mCompositionDisplay->setLayerStackFilter(stack, isPrimary());
+ mCompositionDisplay->setLayerStackFilter(stack, isInternal());
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->setLayerStack(stack);
+ }
+}
+
+void DisplayDevice::setFlags(uint32_t flags) {
+ mFlags = flags;
}
void DisplayDevice::setDisplaySize(int width, int height) {
LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
- mCompositionDisplay->setDisplaySize(ui::Size(width, height));
+ const auto size = ui::Size(width, height);
+ mCompositionDisplay->setDisplaySize(size);
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->setViewport(size);
+ }
}
void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
@@ -262,7 +288,7 @@
std::string DisplayDevice::getDebugName() const {
const char* type = "virtual";
if (mConnectionType) {
- type = *mConnectionType == ui::DisplayConnectionType::Internal ? "internal" : "external";
+ type = isInternal() ? "internal" : "external";
}
return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
@@ -292,6 +318,10 @@
}
result.append("\n");
getCompositionDisplay()->dump(result);
+
+ if (mRefreshRateConfigs) {
+ mRefreshRateConfigs->dump(result);
+ }
}
bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const {
@@ -378,6 +408,80 @@
capabilities.getDesiredMinLuminance());
}
+void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
+ if (!enable) {
+ mRefreshRateOverlay.reset();
+ return;
+ }
+
+ const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange();
+ mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(),
+ highFps.getIntValue(), showSpinnner);
+ mRefreshRateOverlay->setLayerStack(getLayerStack());
+ mRefreshRateOverlay->setViewport(getSize());
+ mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
+}
+
+bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
+ bool timerExpired) {
+ if (mRefreshRateConfigs && mRefreshRateOverlay) {
+ const auto newRefreshRate =
+ mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
+ if (newRefreshRate) {
+ mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void DisplayDevice::onInvalidate() {
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->onInvalidate();
+ }
+}
+
+bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) {
+ ATRACE_CALL();
+
+ LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided");
+ LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch");
+
+ ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str());
+
+ std::scoped_lock lock(mActiveModeLock);
+ if (mDesiredActiveModeChanged) {
+ // If a mode change is pending, just cache the latest request in mDesiredActiveMode
+ const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event;
+ mDesiredActiveMode = info;
+ mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig;
+ return false;
+ }
+
+ // Check if we are already at the desired mode
+ if (getActiveMode()->getId() == info.mode->getId()) {
+ return false;
+ }
+
+ // Initiate a mode change.
+ mDesiredActiveModeChanged = true;
+ mDesiredActiveMode = info;
+ return true;
+}
+
+std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const {
+ std::scoped_lock lock(mActiveModeLock);
+ if (mDesiredActiveModeChanged) return mDesiredActiveMode;
+ return std::nullopt;
+}
+
+void DisplayDevice::clearDesiredActiveModeState() {
+ std::scoped_lock lock(mActiveModeLock);
+ mDesiredActiveMode.event = Scheduler::ModeEvent::None;
+ mDesiredActiveModeChanged = false;
+}
+
std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 7e4d923..afd12b5 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -39,17 +39,24 @@
#include <utils/RefBase.h>
#include <utils/Timers.h>
+#include "MainThreadGuard.h"
+
#include "DisplayHardware/DisplayIdentification.h"
#include "DisplayHardware/DisplayMode.h"
#include "DisplayHardware/Hal.h"
#include "DisplayHardware/PowerAdvisor.h"
+#include "Scheduler/RefreshRateConfigs.h"
+
+#include "TracedOrdinal.h"
+
namespace android {
class Fence;
class HWComposer;
class IGraphicBufferProducer;
class Layer;
+class RefreshRateOverlay;
class SurfaceFlinger;
struct CompositionInfo;
@@ -64,6 +71,7 @@
public:
constexpr static float sDefaultMinLumiance = 0.0;
constexpr static float sDefaultMaxLumiance = 500.0;
+ enum { eReceivesInput = 0x01 };
explicit DisplayDevice(DisplayDeviceCreationArgs& args);
@@ -78,6 +86,9 @@
bool isVirtual() const { return !mConnectionType; }
bool isPrimary() const { return mIsPrimary; }
+ bool isInternal() const {
+ return !isVirtual() && mConnectionType == ui::DisplayConnectionType::Internal;
+ }
// isSecure indicates whether this display can be trusted to display
// secure surfaces.
@@ -90,6 +101,7 @@
void setLayerStack(ui::LayerStack);
void setDisplaySize(int width, int height);
void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
+ void setFlags(uint32_t flags);
ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; }
ui::Rotation getOrientation() const { return mOrientation; }
@@ -102,6 +114,7 @@
const Rect& getOrientedDisplaySpaceRect() const;
bool needsFiltering() const;
ui::LayerStack getLayerStack() const;
+ bool receivesInput() const { return mFlags & eReceivesInput; }
DisplayId getId() const;
@@ -172,10 +185,28 @@
* Display mode management.
*/
const DisplayModePtr& getActiveMode() const;
- void setActiveMode(DisplayModeId);
- status_t initiateModeChange(DisplayModeId modeId,
+
+ struct ActiveModeInfo {
+ DisplayModePtr mode;
+ scheduler::RefreshRateConfigEvent event = scheduler::RefreshRateConfigEvent::None;
+
+ bool operator!=(const ActiveModeInfo& other) const {
+ return mode != other.mode || event != other.event;
+ }
+ };
+
+ bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock);
+ std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock);
+ void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock);
+ ActiveModeInfo getUpcomingActiveMode() const REQUIRES(SF_MAIN_THREAD) {
+ return mUpcomingActiveMode;
+ }
+
+ void setActiveMode(DisplayModeId) REQUIRES(SF_MAIN_THREAD);
+ status_t initiateModeChange(const ActiveModeInfo&,
const hal::VsyncPeriodChangeConstraints& constraints,
- hal::VsyncPeriodChangeTimeline* outTimeline) const;
+ hal::VsyncPeriodChangeTimeline* outTimeline)
+ REQUIRES(SF_MAIN_THREAD);
// Return the immutable list of supported display modes. The HWC may report different modes
// after a hotplug reconnect event, in which case the DisplayDevice object will be recreated.
@@ -187,6 +218,22 @@
// set-top boxes after a hotplug reconnect.
DisplayModePtr getMode(DisplayModeId) const;
+ // Returns the refresh rate configs for this display.
+ scheduler::RefreshRateConfigs& refreshRateConfigs() const { return *mRefreshRateConfigs; }
+
+ // Returns a shared pointer to the refresh rate configs for this display.
+ // Clients can store this refresh rate configs and use it even if the DisplayDevice
+ // is destroyed.
+ std::shared_ptr<scheduler::RefreshRateConfigs> holdRefreshRateConfigs() const {
+ return mRefreshRateConfigs;
+ }
+
+ // Enables an overlay to be displayed with the current refresh rate
+ void enableRefreshRateOverlay(bool enable, bool showSpinner);
+ bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
+ bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
+ void onInvalidate();
+
void onVsync(nsecs_t timestamp);
nsecs_t getVsyncPeriodFromHWC() const;
nsecs_t getRefreshTimestamp() const;
@@ -211,6 +258,8 @@
const std::shared_ptr<compositionengine::Display> mCompositionDisplay;
std::string mDisplayName;
+ std::string mActiveModeFPSTrace;
+ std::string mActiveModeFPSHwcTrace;
const ui::Rotation mPhysicalOrientation;
ui::Rotation mOrientation = ui::ROTATION_0;
@@ -227,9 +276,20 @@
// TODO(b/74619554): Remove special cases for primary display.
const bool mIsPrimary;
+ uint32_t mFlags = 0;
+
std::optional<DeviceProductInfo> mDeviceProductInfo;
std::vector<ui::Hdr> mOverrideHdrTypes;
+
+ std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
+ std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay;
+
+ mutable std::mutex mActiveModeLock;
+ ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock);
+ TracedOrdinal<bool> mDesiredActiveModeChanged
+ GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false};
+ ActiveModeInfo mUpcomingActiveMode GUARDED_BY(SF_MAIN_THREAD);
};
struct DisplayDeviceState {
@@ -252,6 +312,7 @@
std::optional<Physical> physical;
sp<IGraphicBufferProducer> surface;
ui::LayerStack layerStack = ui::NO_LAYER_STACK;
+ uint32_t flags = 0;
Rect layerStackSpaceRect;
Rect orientedDisplaySpaceRect;
ui::Rotation orientation = ui::ROTATION_0;
@@ -274,6 +335,7 @@
HWComposer& hwComposer;
const wp<IBinder> displayToken;
const std::shared_ptr<compositionengine::Display> compositionDisplay;
+ std::shared_ptr<scheduler::RefreshRateConfigs> refreshRateConfigs;
int32_t sequenceId{0};
std::optional<ui::DisplayConnectionType> connectionType;
@@ -289,18 +351,7 @@
hardware::graphics::composer::hal::PowerMode::ON};
bool isPrimary{false};
DisplayModes supportedModes;
-};
-
-// Predicates for display lookup.
-
-struct WithLayerStack {
- explicit WithLayerStack(ui::LayerStack layerStack) : layerStack(layerStack) {}
-
- bool operator()(const DisplayDevice& display) const {
- return display.getLayerStack() == layerStack;
- }
-
- ui::LayerStack layerStack;
+ DisplayModeId activeModeId;
};
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
index 98209bb..83c2b2e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
@@ -25,6 +25,7 @@
#include <log/log.h>
#include "DisplayIdentification.h"
+#include "Hash.h"
namespace android {
namespace {
@@ -262,8 +263,9 @@
}
// Hash model string instead of using product code or (integer) serial number, since the latter
- // have been observed to change on some displays with multiple inputs.
- const auto modelHash = static_cast<uint32_t>(std::hash<std::string_view>()(modelString));
+ // have been observed to change on some displays with multiple inputs. Use a stable hash instead
+ // of std::hash which is only required to be same within a single execution of a program.
+ const uint32_t modelHash = static_cast<uint32_t>(cityHash64Len0To16(modelString));
// Parse extension blocks.
std::optional<Cea861ExtensionBlock> cea861Block;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayMode.h b/services/surfaceflinger/DisplayHardware/DisplayMode.h
index 85cc993..5de622b 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayMode.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayMode.h
@@ -22,6 +22,7 @@
#include <android-base/stringprintf.h>
#include <android/configuration.h>
+#include <ui/DisplayId.h>
#include <ui/DisplayMode.h>
#include <ui/Size.h>
#include <utils/Timers.h>
@@ -54,6 +55,11 @@
return *this;
}
+ Builder& setPhysicalDisplayId(PhysicalDisplayId id) {
+ mDisplayMode->mPhysicalDisplayId = id;
+ return *this;
+ }
+
Builder& setWidth(int32_t width) {
mDisplayMode->mWidth = width;
return *this;
@@ -112,6 +118,7 @@
DisplayModeId getId() const { return mId; }
hal::HWConfigId getHwcId() const { return mHwcId; }
+ PhysicalDisplayId getPhysicalDisplayId() const { return mPhysicalDisplayId; }
int32_t getWidth() const { return mWidth; }
int32_t getHeight() const { return mHeight; }
@@ -136,6 +143,7 @@
hal::HWConfigId mHwcId;
DisplayModeId mId;
+ PhysicalDisplayId mPhysicalDisplayId;
int32_t mWidth = -1;
int32_t mHeight = -1;
diff --git a/services/surfaceflinger/DisplayHardware/Hash.cpp b/services/surfaceflinger/DisplayHardware/Hash.cpp
new file mode 100644
index 0000000..6056c8d
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/Hash.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "DisplayIdentification"
+
+#include <cstring>
+#include <type_traits>
+
+#include <log/log.h>
+
+#include "Hash.h"
+
+namespace android {
+namespace {
+
+template <class T>
+inline T load(const void* p) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+
+ T r;
+ std::memcpy(&r, p, sizeof(r));
+ return r;
+}
+
+uint64_t rotateByAtLeast1(uint64_t val, uint8_t shift) {
+ return (val >> shift) | (val << (64 - shift));
+}
+
+uint64_t shiftMix(uint64_t val) {
+ return val ^ (val >> 47);
+}
+
+uint64_t hash64Len16(uint64_t u, uint64_t v) {
+ constexpr uint64_t kMul = 0x9ddfea08eb382d69;
+ uint64_t a = (u ^ v) * kMul;
+ a ^= (a >> 47);
+ uint64_t b = (v ^ a) * kMul;
+ b ^= (b >> 47);
+ b *= kMul;
+ return b;
+}
+
+uint64_t hash64Len0To16(const char* s, uint64_t len) {
+ constexpr uint64_t k2 = 0x9ae16a3b2f90404f;
+ constexpr uint64_t k3 = 0xc949d7c7509e6557;
+
+ if (len > 8) {
+ const uint64_t a = load<uint64_t>(s);
+ const uint64_t b = load<uint64_t>(s + len - 8);
+ return hash64Len16(a, rotateByAtLeast1(b + len, static_cast<uint8_t>(len))) ^ b;
+ }
+ if (len >= 4) {
+ const uint32_t a = load<uint32_t>(s);
+ const uint32_t b = load<uint32_t>(s + len - 4);
+ return hash64Len16(len + (a << 3), b);
+ }
+ if (len > 0) {
+ const unsigned char a = static_cast<unsigned char>(s[0]);
+ const unsigned char b = static_cast<unsigned char>(s[len >> 1]);
+ const unsigned char c = static_cast<unsigned char>(s[len - 1]);
+ const uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
+ const uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
+ return shiftMix(y * k2 ^ z * k3) * k2;
+ }
+ return k2;
+}
+
+} // namespace
+
+uint64_t cityHash64Len0To16(std::string_view sv) {
+ auto len = sv.length();
+ if (len > 16) {
+ ALOGE("%s called with length %zu. Only hashing the first 16 chars", __FUNCTION__, len);
+ len = 16;
+ }
+ return hash64Len0To16(sv.data(), len);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/ui/Size.cpp b/services/surfaceflinger/DisplayHardware/Hash.h
similarity index 65%
copy from libs/ui/Size.cpp
copy to services/surfaceflinger/DisplayHardware/Hash.h
index d2996d1..a7b6c71 100644
--- a/libs/ui/Size.cpp
+++ b/services/surfaceflinger/DisplayHardware/Hash.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 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,14 @@
* limitations under the License.
*/
-#include <ui/Size.h>
+#pragma once
-namespace android::ui {
+#include <cstdint>
+#include <string_view>
-const Size Size::INVALID{-1, -1};
-const Size Size::EMPTY{0, 0};
+namespace android {
-} // namespace android::ui
+// CityHash64 implementation that only hashes at most the first 16 characters of the given string.
+uint64_t cityHash64Len0To16(std::string_view sv);
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index dbd2793..db59007 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -71,7 +71,6 @@
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
#include "TunnelModeEnabledReporter.h"
-#include "input/InputWindow.h"
#define DEBUG_RESIZE 0
@@ -83,6 +82,7 @@
using base::StringAppendF;
using namespace android::flag_operators;
using PresentState = frametimeline::SurfaceFrame::PresentState;
+using gui::WindowInfo;
std::atomic<int32_t> Layer::sSequence{1};
@@ -90,8 +90,8 @@
: mFlinger(args.flinger),
mName(args.name),
mClientRef(args.client),
- mWindowType(static_cast<InputWindowInfo::Type>(
- args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
+ mWindowType(
+ static_cast<WindowInfo::Type>(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
uint32_t layerFlags = 0;
if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
@@ -819,11 +819,7 @@
}
bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
- sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
- if (handle == nullptr) {
- return false;
- }
- sp<Layer> relative = handle->owner.promote();
+ sp<Layer> relative = fromHandle(relativeToHandle).promote();
if (relative == nullptr) {
return false;
}
@@ -1615,8 +1611,7 @@
bool Layer::reparent(const sp<IBinder>& newParentHandle) {
sp<Layer> newParent;
if (newParentHandle != nullptr) {
- auto handle = static_cast<Handle*>(newParentHandle.get());
- newParent = handle->owner.promote();
+ newParent = fromHandle(newParentHandle).promote();
if (newParent == nullptr) {
ALOGE("Unable to promote Layer handle");
return false;
@@ -1991,24 +1986,10 @@
mDrawingParent = mCurrentParent;
}
-static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) {
- if (weakBinderHandle == nullptr) {
- return nullptr;
- }
- sp<IBinder> binderHandle = weakBinderHandle.promote();
- if (binderHandle == nullptr) {
- return nullptr;
- }
- sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get());
- if (handle == nullptr) {
- return nullptr;
- }
- return handle->owner;
-}
-void Layer::setInputInfo(const InputWindowInfo& info) {
+void Layer::setInputInfo(const WindowInfo& info) {
mDrawingState.inputInfo = info;
- mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
+ mDrawingState.touchableRegionCrop = fromHandle(info.touchableRegionCropHandle.promote());
mDrawingState.modified = true;
mFlinger->mInputInfoChanged = true;
setTransactionFlags(eTransactionNeeded);
@@ -2157,7 +2138,7 @@
}
if (traceFlags & SurfaceTracing::TRACE_INPUT) {
- InputWindowInfo info;
+ WindowInfo info;
if (useDrawing) {
info = fillInputInfo({nullptr});
} else {
@@ -2188,7 +2169,7 @@
return getCroppedBufferSize(getDrawingState());
}
-void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay) {
+void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& toPhysicalDisplay) {
// Transform layer size to screen space and inset it by surface insets.
// If this is a portal window, set the touchableRegion to the layerBounds.
Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE
@@ -2283,7 +2264,7 @@
info.touchableRegion = inputTransform.transform(info.touchableRegion);
}
-void Layer::fillTouchOcclusionMode(InputWindowInfo& info) {
+void Layer::fillTouchOcclusionMode(WindowInfo& info) {
sp<Layer> p = this;
while (p != nullptr && !p->hasInputInfo()) {
p = p->mDrawingParent.promote();
@@ -2293,17 +2274,17 @@
}
}
-InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) {
+WindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) {
if (!hasInputInfo()) {
mDrawingState.inputInfo.name = getName();
mDrawingState.inputInfo.ownerUid = mOwnerUid;
mDrawingState.inputInfo.ownerPid = mOwnerPid;
- mDrawingState.inputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL;
- mDrawingState.inputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
+ mDrawingState.inputInfo.inputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
+ mDrawingState.inputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
mDrawingState.inputInfo.displayId = getLayerStack();
}
- InputWindowInfo info = mDrawingState.inputInfo;
+ WindowInfo info = mDrawingState.inputInfo;
info.id = sequence;
if (info.displayId == ADISPLAY_ID_NONE) {
@@ -2315,6 +2296,10 @@
ui::Transform toPhysicalDisplay;
if (display) {
toPhysicalDisplay = display->getTransform();
+ // getOrientation() without masking can contain more-significant bits (eg. ROT_INVALID).
+ static constexpr uint32_t ALL_ROTATIONS_MASK =
+ ui::Transform::ROT_90 | ui::Transform::ROT_180 | ui::Transform::ROT_270;
+ info.displayOrientation = toPhysicalDisplay.getOrientation() & ALL_ROTATIONS_MASK;
info.displayWidth = display->getWidth();
info.displayHeight = display->getHeight();
}
@@ -2482,7 +2467,7 @@
}
// Cloned layers shouldn't handle watch outside since their z order is not determined by
// WM or the client.
- mDrawingState.inputInfo.flags &= ~InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH;
+ mDrawingState.inputInfo.flags &= ~WindowInfo::Flag::WATCH_OUTSIDE_TOUCH;
}
void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
@@ -2567,6 +2552,23 @@
mFlinger->mNumClones++;
}
+const String16 Layer::Handle::kDescriptor = String16("android.Layer.Handle");
+
+wp<Layer> Layer::fromHandle(const sp<IBinder>& handleBinder) {
+ if (handleBinder == nullptr) {
+ return nullptr;
+ }
+
+ BBinder* b = handleBinder->localBinder();
+ if (b == nullptr || b->getInterfaceDescriptor() != Handle::kDescriptor) {
+ return nullptr;
+ }
+
+ // We can safely cast this binder since its local and we verified its interface descriptor.
+ sp<Handle> handle = static_cast<Handle*>(handleBinder.get());
+ return handle->owner;
+}
+
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c5cb17f..3ed7ee9 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -21,7 +21,7 @@
#include <gui/BufferQueue.h>
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
#include <layerproto/LayerProtoHeader.h>
#include <math/vec4.h>
#include <renderengine/Mesh.h>
@@ -186,7 +186,7 @@
float cornerRadius;
int backgroundBlurRadius;
- InputWindowInfo inputInfo;
+ gui::WindowInfo inputInfo;
wp<Layer> touchableRegionCrop;
// dataspace is only used by BufferStateLayer and EffectLayer
@@ -289,16 +289,17 @@
class LayerCleaner {
sp<SurfaceFlinger> mFlinger;
sp<Layer> mLayer;
+ BBinder* mHandle;
protected:
~LayerCleaner() {
// destroy client resources
- mFlinger->onHandleDestroyed(mLayer);
+ mFlinger->onHandleDestroyed(mHandle, mLayer);
}
public:
- LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
- : mFlinger(flinger), mLayer(layer) {}
+ LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer, BBinder* handle)
+ : mFlinger(flinger), mLayer(layer), mHandle(handle) {}
};
/*
@@ -312,11 +313,15 @@
class Handle : public BBinder, public LayerCleaner {
public:
Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
- : LayerCleaner(flinger, layer), owner(layer) {}
+ : LayerCleaner(flinger, layer, this), owner(layer) {}
+ const String16& getInterfaceDescriptor() const override { return kDescriptor; }
+ static const String16 kDescriptor;
wp<Layer> owner;
};
+ static wp<Layer> fromHandle(const sp<IBinder>& handle);
+
explicit Layer(const LayerCreationArgs& args);
virtual ~Layer();
@@ -690,7 +695,7 @@
void writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet,
uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
- InputWindowInfo::Type getWindowType() const { return mWindowType; }
+ gui::WindowInfo::Type getWindowType() const { return mWindowType; }
bool getPrimaryDisplayOnly() const;
@@ -847,9 +852,9 @@
sp<IBinder> getHandle();
const std::string& getName() const { return mName; }
bool getPremultipledAlpha() const;
- void setInputInfo(const InputWindowInfo& info);
+ void setInputInfo(const gui::WindowInfo& info);
- InputWindowInfo fillInputInfo(const sp<DisplayDevice>& display);
+ gui::WindowInfo fillInputInfo(const sp<DisplayDevice>& display);
/**
* Returns whether this layer has an explicitly set input-info.
*/
@@ -1014,7 +1019,7 @@
wp<Layer> mDrawingParent;
// Window types from WindowManager.LayoutParams
- const InputWindowInfo::Type mWindowType;
+ const gui::WindowInfo::Type mWindowType;
// The owner of the layer. If created from a non system process, it will be the calling uid.
// If created from a system process, the value can be passed in.
@@ -1066,10 +1071,10 @@
// Fills in the touch occlusion mode of the first parent (including this layer) that
// hasInputInfo() or no-op if no such parent is found.
- void fillTouchOcclusionMode(InputWindowInfo& info);
+ void fillTouchOcclusionMode(gui::WindowInfo& info);
- // Fills in the frame and transform info for the InputWindowInfo
- void fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay);
+ // Fills in the frame and transform info for the gui::WindowInfo
+ void fillInputFrameInfo(gui::WindowInfo& info, const ui::Transform& toPhysicalDisplay);
bool updateFrameRateForLayerTree(bool treeHasFrameRateVote);
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index b1db6d3..79f7b1f 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -22,6 +22,9 @@
#include "LayerProtoHelper.h"
namespace android {
+
+using gui::WindowInfo;
+
namespace surfaceflinger {
void LayerProtoHelper::writePositionToProto(const float x, const float y,
@@ -125,7 +128,7 @@
}
void LayerProtoHelper::writeToProto(
- const InputWindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
+ const WindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
std::function<InputWindowInfoProto*()> getInputWindowInfoProto) {
if (inputInfo.token == nullptr) {
return;
@@ -133,7 +136,7 @@
InputWindowInfoProto* proto = getInputWindowInfoProto();
proto->set_layout_params_flags(inputInfo.flags.get());
- using U = std::underlying_type_t<InputWindowInfo::Type>;
+ using U = std::underlying_type_t<WindowInfo::Type>;
// TODO(b/129481165): This static assert can be safely removed once conversion warnings
// are re-enabled.
static_assert(std::is_same_v<U, int32_t>);
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 502238d..187ce3d 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -17,7 +17,7 @@
#include <layerproto/LayerProtoHeader.h>
#include <Layer.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
#include <math/vec4.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
@@ -40,7 +40,7 @@
static void writeToProto(const ui::Transform& transform, TransformProto* transformProto);
static void writeToProto(const sp<GraphicBuffer>& buffer,
std::function<ActiveBufferProto*()> getActiveBufferProto);
- static void writeToProto(const InputWindowInfo& inputInfo,
+ static void writeToProto(const gui::WindowInfo& inputInfo,
const wp<Layer>& touchableRegionBounds,
std::function<InputWindowInfoProto*()> getInputWindowInfoProto);
static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto);
diff --git a/services/surfaceflinger/MainThreadGuard.h b/services/surfaceflinger/MainThreadGuard.h
new file mode 100644
index 0000000..c1aa118
--- /dev/null
+++ b/services/surfaceflinger/MainThreadGuard.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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 <utils/Mutex.h>
+
+namespace android {
+namespace {
+
+// Helps to ensure that some functions runs on SF's main thread by using the
+// clang thread safety annotations.
+class CAPABILITY("mutex") MainThreadGuard {
+} SF_MAIN_THREAD;
+
+struct SCOPED_CAPABILITY MainThreadScopedGuard {
+public:
+ explicit MainThreadScopedGuard(MainThreadGuard& mutex) ACQUIRE(mutex) {}
+ ~MainThreadScopedGuard() RELEASE() {}
+};
+} // namespace
+} // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 27a1c28..2adfe14 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -25,6 +25,10 @@
#include "Client.h"
#include "Layer.h"
+#include <SkBlendMode.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkSurface.h>
#include <gui/IProducerListener.h>
#undef LOG_TAG
@@ -32,85 +36,64 @@
namespace android {
-void RefreshRateOverlay::SevenSegmentDrawer::drawRect(const Rect& r, const half4& color,
- const sp<GraphicBuffer>& buffer,
- uint8_t* pixels) {
- for (int32_t j = r.top; j < r.bottom; j++) {
- if (j >= buffer->getHeight()) {
- break;
- }
-
- for (int32_t i = r.left; i < r.right; i++) {
- if (i >= buffer->getWidth()) {
- break;
- }
-
- uint8_t* iter = pixels + 4 * (i + (buffer->getStride() * j));
- iter[0] = uint8_t(color.r * 255);
- iter[1] = uint8_t(color.g * 255);
- iter[2] = uint8_t(color.b * 255);
- iter[3] = uint8_t(color.a * 255);
- }
- }
-}
-
-void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left,
- const half4& color,
- const sp<GraphicBuffer>& buffer,
- uint8_t* pixels) {
- const Rect rect = [&]() {
+void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left, SkColor& color,
+ SkCanvas& canvas) {
+ const SkRect rect = [&]() {
switch (segment) {
case Segment::Upper:
- return Rect(left, 0, left + DIGIT_WIDTH, DIGIT_SPACE);
+ return SkRect::MakeLTRB(left, 0, left + DIGIT_WIDTH, DIGIT_SPACE);
case Segment::UpperLeft:
- return Rect(left, 0, left + DIGIT_SPACE, DIGIT_HEIGHT / 2);
+ return SkRect::MakeLTRB(left, 0, left + DIGIT_SPACE, DIGIT_HEIGHT / 2);
case Segment::UpperRight:
- return Rect(left + DIGIT_WIDTH - DIGIT_SPACE, 0, left + DIGIT_WIDTH,
- DIGIT_HEIGHT / 2);
+ return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, 0, left + DIGIT_WIDTH,
+ DIGIT_HEIGHT / 2);
case Segment::Middle:
- return Rect(left, DIGIT_HEIGHT / 2 - DIGIT_SPACE / 2, left + DIGIT_WIDTH,
- DIGIT_HEIGHT / 2 + DIGIT_SPACE / 2);
+ return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2 - DIGIT_SPACE / 2,
+ left + DIGIT_WIDTH, DIGIT_HEIGHT / 2 + DIGIT_SPACE / 2);
case Segment::LowerLeft:
- return Rect(left, DIGIT_HEIGHT / 2, left + DIGIT_SPACE, DIGIT_HEIGHT);
+ return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2, left + DIGIT_SPACE, DIGIT_HEIGHT);
case Segment::LowerRight:
- return Rect(left + DIGIT_WIDTH - DIGIT_SPACE, DIGIT_HEIGHT / 2, left + DIGIT_WIDTH,
- DIGIT_HEIGHT);
- case Segment::Buttom:
- return Rect(left, DIGIT_HEIGHT - DIGIT_SPACE, left + DIGIT_WIDTH, DIGIT_HEIGHT);
+ return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, DIGIT_HEIGHT / 2,
+ left + DIGIT_WIDTH, DIGIT_HEIGHT);
+ case Segment::Bottom:
+ return SkRect::MakeLTRB(left, DIGIT_HEIGHT - DIGIT_SPACE, left + DIGIT_WIDTH,
+ DIGIT_HEIGHT);
}
}();
- drawRect(rect, color, buffer, pixels);
+ SkPaint paint;
+ paint.setColor(color);
+ paint.setBlendMode(SkBlendMode::kSrc);
+ canvas.drawRect(rect, paint);
}
-void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, const half4& color,
- const sp<GraphicBuffer>& buffer,
- uint8_t* pixels) {
+void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, SkColor& color,
+ SkCanvas& canvas) {
if (digit < 0 || digit > 9) return;
if (digit == 0 || digit == 2 || digit == 3 || digit == 5 || digit == 6 || digit == 7 ||
digit == 8 || digit == 9)
- drawSegment(Segment::Upper, left, color, buffer, pixels);
+ drawSegment(Segment::Upper, left, color, canvas);
if (digit == 0 || digit == 4 || digit == 5 || digit == 6 || digit == 8 || digit == 9)
- drawSegment(Segment::UpperLeft, left, color, buffer, pixels);
+ drawSegment(Segment::UpperLeft, left, color, canvas);
if (digit == 0 || digit == 1 || digit == 2 || digit == 3 || digit == 4 || digit == 7 ||
digit == 8 || digit == 9)
- drawSegment(Segment::UpperRight, left, color, buffer, pixels);
+ drawSegment(Segment::UpperRight, left, color, canvas);
if (digit == 2 || digit == 3 || digit == 4 || digit == 5 || digit == 6 || digit == 8 ||
digit == 9)
- drawSegment(Segment::Middle, left, color, buffer, pixels);
+ drawSegment(Segment::Middle, left, color, canvas);
if (digit == 0 || digit == 2 || digit == 6 || digit == 8)
- drawSegment(Segment::LowerLeft, left, color, buffer, pixels);
+ drawSegment(Segment::LowerLeft, left, color, canvas);
if (digit == 0 || digit == 1 || digit == 3 || digit == 4 || digit == 5 || digit == 6 ||
digit == 7 || digit == 8 || digit == 9)
- drawSegment(Segment::LowerRight, left, color, buffer, pixels);
+ drawSegment(Segment::LowerRight, left, color, canvas);
if (digit == 0 || digit == 2 || digit == 3 || digit == 5 || digit == 6 || digit == 8 ||
digit == 9)
- drawSegment(Segment::Buttom, left, color, buffer, pixels);
+ drawSegment(Segment::Bottom, left, color, canvas);
}
-std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(
- int number, const half4& color, bool showSpinner) {
+std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::draw(
+ int number, SkColor& color, ui::Transform::RotationFlags rotation, bool showSpinner) {
if (number < 0 || number > 1000) return {};
const auto hundreds = number / 100;
@@ -120,65 +103,90 @@
std::vector<sp<GraphicBuffer>> buffers;
const auto loopCount = showSpinner ? 6 : 1;
for (int i = 0; i < loopCount; i++) {
+ // Pre-rotate the buffer before it reaches SurfaceFlinger.
+ SkMatrix canvasTransform = SkMatrix();
+ auto [bufferWidth, bufferHeight] = [&] {
+ switch (rotation) {
+ case ui::Transform::ROT_90:
+ canvasTransform.setTranslate(BUFFER_HEIGHT, 0);
+ canvasTransform.preRotate(90);
+ return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+ case ui::Transform::ROT_270:
+ canvasTransform.setRotate(270, BUFFER_WIDTH / 2.0, BUFFER_WIDTH / 2.0);
+ return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+ default:
+ return std::make_tuple(BUFFER_WIDTH, BUFFER_HEIGHT);
+ }
+ }();
sp<GraphicBuffer> buffer =
- new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ new GraphicBuffer(bufferWidth, bufferHeight, HAL_PIXEL_FORMAT_RGBA_8888, 1,
GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
GRALLOC_USAGE_HW_TEXTURE,
"RefreshRateOverlayBuffer");
const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "RefreshRateOverlay: Buffer failed to allocate: %d",
bufferStatus);
- uint8_t* pixels;
- buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
- // Clear buffer content
- drawRect(Rect(BUFFER_WIDTH, BUFFER_HEIGHT), half4(0), buffer, pixels);
+
+ sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(bufferWidth, bufferHeight);
+ SkCanvas* canvas = surface->getCanvas();
+ canvas->setMatrix(canvasTransform);
+
int left = 0;
if (hundreds != 0) {
- drawDigit(hundreds, left, color, buffer, pixels);
+ drawDigit(hundreds, left, color, *canvas);
}
left += DIGIT_WIDTH + DIGIT_SPACE;
if (tens != 0) {
- drawDigit(tens, left, color, buffer, pixels);
+ drawDigit(tens, left, color, *canvas);
}
left += DIGIT_WIDTH + DIGIT_SPACE;
- drawDigit(ones, left, color, buffer, pixels);
+ drawDigit(ones, left, color, *canvas);
left += DIGIT_WIDTH + DIGIT_SPACE;
if (showSpinner) {
switch (i) {
case 0:
- drawSegment(Segment::Upper, left, color, buffer, pixels);
+ drawSegment(Segment::Upper, left, color, *canvas);
break;
case 1:
- drawSegment(Segment::UpperRight, left, color, buffer, pixels);
+ drawSegment(Segment::UpperRight, left, color, *canvas);
break;
case 2:
- drawSegment(Segment::LowerRight, left, color, buffer, pixels);
+ drawSegment(Segment::LowerRight, left, color, *canvas);
break;
case 3:
- drawSegment(Segment::Buttom, left, color, buffer, pixels);
+ drawSegment(Segment::Bottom, left, color, *canvas);
break;
case 4:
- drawSegment(Segment::LowerLeft, left, color, buffer, pixels);
+ drawSegment(Segment::LowerLeft, left, color, *canvas);
break;
case 5:
- drawSegment(Segment::UpperLeft, left, color, buffer, pixels);
+ drawSegment(Segment::UpperLeft, left, color, *canvas);
break;
}
}
+ void* pixels = nullptr;
+ buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
+ const SkImageInfo& imageInfo = surface->imageInfo();
+ size_t dstRowBytes = buffer->getStride() * imageInfo.bytesPerPixel();
+ canvas->readPixels(imageInfo, pixels, dstRowBytes, 0, 0);
buffer->unlock();
buffers.emplace_back(buffer);
}
return buffers;
}
-RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, bool showSpinner)
- : mFlinger(flinger), mClient(new Client(&mFlinger)), mShowSpinner(showSpinner) {
+RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, uint32_t lowFps, uint32_t highFps,
+ bool showSpinner)
+ : mFlinger(flinger),
+ mClient(new Client(&mFlinger)),
+ mShowSpinner(showSpinner),
+ mLowFps(lowFps),
+ mHighFps(highFps) {
createLayer();
- reset();
}
bool RefreshRateOverlay::createLayer() {
@@ -194,7 +202,6 @@
return false;
}
- Mutex::Autolock _l(mFlinger.mStateLock);
mLayer = mClient->getLayerUser(mIBinder);
mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));
mLayer->setIsAtRoot(true);
@@ -211,7 +218,22 @@
const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
- if (mBufferCache.find(fps) == mBufferCache.end()) {
+ ui::Transform::RotationFlags transformHint = mLayer->getTransformHint();
+ // Tell SurfaceFlinger about the pre-rotation on the buffer.
+ const auto transform = [&] {
+ switch (transformHint) {
+ case ui::Transform::ROT_90:
+ return ui::Transform::ROT_270;
+ case ui::Transform::ROT_270:
+ return ui::Transform::ROT_90;
+ default:
+ return ui::Transform::ROT_0;
+ }
+ }();
+ mLayer->setTransform(transform);
+
+ if (mBufferCache.find(transformHint) == mBufferCache.end() ||
+ mBufferCache.at(transformHint).find(fps) == mBufferCache.at(transformHint).end()) {
// Ensure the range is > 0, so we don't divide by 0.
const auto rangeLength = std::max(1u, mHighFps - mLowFps);
// Clip values outside the range [mLowFps, mHighFps]. The current fps may be outside
@@ -219,12 +241,14 @@
fps = std::max(fps, mLowFps);
fps = std::min(fps, mHighFps);
const auto fpsScale = static_cast<float>(fps - mLowFps) / rangeLength;
- half4 color;
- color.r = HIGH_FPS_COLOR.r * fpsScale + LOW_FPS_COLOR.r * (1 - fpsScale);
- color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
- color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
- color.a = ALPHA;
- auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner);
+ SkColor4f colorBase = SkColor4f::FromColor(HIGH_FPS_COLOR) * fpsScale;
+ SkColor4f lowFpsColor = SkColor4f::FromColor(LOW_FPS_COLOR) * (1 - fpsScale);
+ colorBase.fR = colorBase.fR + lowFpsColor.fR;
+ colorBase.fG = colorBase.fG + lowFpsColor.fG;
+ colorBase.fB = colorBase.fB + lowFpsColor.fB;
+ colorBase.fA = ALPHA;
+ SkColor color = colorBase.toSkColor();
+ auto buffers = SevenSegmentDrawer::draw(fps, color, transformHint, mShowSpinner);
std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
[&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
@@ -234,15 +258,18 @@
renderengine::ExternalTexture::
Usage::READABLE);
});
- mBufferCache.emplace(fps, textures);
+ mBufferCache[transformHint].emplace(fps, textures);
}
- return mBufferCache[fps];
+ return mBufferCache[transformHint][fps];
}
void RefreshRateOverlay::setViewport(ui::Size viewport) {
- Rect frame((3 * viewport.width) >> 4, viewport.height >> 5);
- frame.offsetBy(viewport.width >> 5, viewport.height >> 4);
+ constexpr int32_t kMaxWidth = 1000;
+ const auto width = std::min(kMaxWidth, std::min(viewport.width, viewport.height));
+ const auto height = 2 * width;
+ Rect frame((3 * width) >> 4, height >> 5);
+ frame.offsetBy(width >> 5, height >> 4);
layer_state_t::matrix22_t matrix;
matrix.dsdx = frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth());
@@ -254,6 +281,11 @@
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}
+void RefreshRateOverlay::setLayerStack(uint32_t stack) {
+ mLayer->setLayerStack(stack);
+ mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+}
+
void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
mCurrentFps = fps.getIntValue();
auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
@@ -279,13 +311,6 @@
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}
-void RefreshRateOverlay::reset() {
- mBufferCache.clear();
- const auto range = mFlinger.mRefreshRateConfigs->getSupportedRefreshRateRange();
- mLowFps = range.min.getIntValue();
- mHighFps = range.max.getIntValue();
-}
-
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index aa8329c..fd1e2df 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -22,6 +22,8 @@
#include <ui/Size.h>
#include <utils/StrongPointer.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
#include <unordered_map>
#include "Fps.h"
@@ -37,30 +39,26 @@
class RefreshRateOverlay {
public:
- RefreshRateOverlay(SurfaceFlinger&, bool showSpinner);
+ RefreshRateOverlay(SurfaceFlinger&, uint32_t lowFps, uint32_t highFps, bool showSpinner);
+ void setLayerStack(uint32_t stack);
void setViewport(ui::Size);
void changeRefreshRate(const Fps&);
void onInvalidate();
- void reset();
private:
class SevenSegmentDrawer {
public:
- static std::vector<sp<GraphicBuffer>> drawNumber(int number, const half4& color,
- bool showSpinner);
+ static std::vector<sp<GraphicBuffer>> draw(int number, SkColor& color,
+ ui::Transform::RotationFlags, bool showSpinner);
static uint32_t getHeight() { return BUFFER_HEIGHT; }
static uint32_t getWidth() { return BUFFER_WIDTH; }
private:
- enum class Segment { Upper, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, Buttom };
+ enum class Segment { Upper, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, Bottom };
- static void drawRect(const Rect& r, const half4& color, const sp<GraphicBuffer>& buffer,
- uint8_t* pixels);
- static void drawSegment(Segment segment, int left, const half4& color,
- const sp<GraphicBuffer>& buffer, uint8_t* pixels);
- static void drawDigit(int digit, int left, const half4& color,
- const sp<GraphicBuffer>& buffer, uint8_t* pixels);
+ static void drawSegment(Segment segment, int left, SkColor& color, SkCanvas& canvas);
+ static void drawDigit(int digit, int left, SkColor& color, SkCanvas& canvas);
static constexpr uint32_t DIGIT_HEIGHT = 100;
static constexpr uint32_t DIGIT_WIDTH = 64;
@@ -80,19 +78,21 @@
sp<IBinder> mIBinder;
sp<IGraphicBufferProducer> mGbp;
- std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>
+ std::unordered_map<
+ ui::Transform::RotationFlags,
+ std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>>
mBufferCache;
std::optional<int> mCurrentFps;
int mFrame = 0;
static constexpr float ALPHA = 0.8f;
- const half3 LOW_FPS_COLOR = half3(1.0f, 0.0f, 0.0f);
- const half3 HIGH_FPS_COLOR = half3(0.0f, 1.0f, 0.0f);
+ const SkColor LOW_FPS_COLOR = SK_ColorRED;
+ const SkColor HIGH_FPS_COLOR = SK_ColorGREEN;
const bool mShowSpinner;
// Interpolate the colors between these values.
- uint32_t mLowFps;
- uint32_t mHighFps;
+ const uint32_t mLowFps;
+ const uint32_t mHighFps;
};
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 2321e2d..2bdcaf6 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -118,12 +118,12 @@
return event;
}
-DisplayEventReceiver::Event makeModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+DisplayEventReceiver::Event makeModeChanged(DisplayModePtr mode) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, displayId, systemTime()};
- event.modeChange.modeId = modeId.value();
- event.modeChange.vsyncPeriod = vsyncPeriod;
+ event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, mode->getPhysicalDisplayId(),
+ systemTime()};
+ event.modeChange.modeId = mode->getId().value();
+ event.modeChange.vsyncPeriod = mode->getVsyncPeriod();
return event;
}
@@ -375,11 +375,10 @@
mCondition.notify_all();
}
-void EventThread::onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+void EventThread::onModeChanged(DisplayModePtr mode) {
std::lock_guard<std::mutex> lock(mMutex);
- mPendingEvents.push_back(makeModeChanged(displayId, modeId, vsyncPeriod));
+ mPendingEvents.push_back(makeModeChanged(mode));
mCondition.notify_all();
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 1e6793f..9265a25 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -124,8 +124,7 @@
virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
// called when SF changes the active mode and apps needs to be notified about the change
- virtual void onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) = 0;
+ virtual void onModeChanged(DisplayModePtr) = 0;
// called when SF updates the Frame Rate Override list
virtual void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
@@ -174,8 +173,7 @@
void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
- void onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) override;
+ void onModeChanged(DisplayModePtr) override;
void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
std::vector<FrameRateOverride> overrides) override;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 0563795..84e3548 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -75,10 +75,9 @@
}
} // namespace
-LayerHistory::LayerHistory(const RefreshRateConfigs& refreshRateConfigs)
+LayerHistory::LayerHistory()
: mTraceEnabled(traceEnabled()), mUseFrameRatePriority(useFrameRatePriority()) {
LayerInfo::setTraceEnabled(mTraceEnabled);
- LayerInfo::setRefreshRateConfigs(refreshRateConfigs);
}
LayerHistory::~LayerHistory() = default;
@@ -138,7 +137,8 @@
}
}
-LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
+LayerHistory::Summary LayerHistory::summarize(const RefreshRateConfigs& refreshRateConfigs,
+ nsecs_t now) {
LayerHistory::Summary summary;
std::lock_guard lock(mLock);
@@ -151,7 +151,7 @@
ALOGV("%s has priority: %d %s focused", info->getName().c_str(), frameRateSelectionPriority,
layerFocused ? "" : "not");
- const auto vote = info->getRefreshRateVote(now);
+ const auto vote = info->getRefreshRateVote(refreshRateConfigs, now);
// Skip NoVote layer as those don't have any requirements
if (vote.type == LayerHistory::LayerVoteType::NoVote) {
continue;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
index 82f6c39..92236f5 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.h
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -42,7 +42,7 @@
public:
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
- LayerHistory(const RefreshRateConfigs&);
+ LayerHistory();
~LayerHistory();
// Layers are unregistered when the weak reference expires.
@@ -67,7 +67,7 @@
using Summary = std::vector<RefreshRateConfigs::LayerRequirement>;
// Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
- Summary summarize(nsecs_t now);
+ Summary summarize(const RefreshRateConfigs&, nsecs_t now);
void clear();
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 989bf4e..8a45b66 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -34,7 +34,6 @@
namespace android::scheduler {
-const RefreshRateConfigs* LayerInfo::sRefreshRateConfigs = nullptr;
bool LayerInfo::sTraceEnabled = false;
LayerInfo::LayerInfo(const std::string& name, uid_t ownerUid,
@@ -184,7 +183,8 @@
return static_cast<nsecs_t>(averageFrameTime);
}
-std::optional<Fps> LayerInfo::calculateRefreshRateIfPossible(nsecs_t now) {
+std::optional<Fps> LayerInfo::calculateRefreshRateIfPossible(
+ const RefreshRateConfigs& refreshRateConfigs, nsecs_t now) {
static constexpr float MARGIN = 1.0f; // 1Hz
if (!hasEnoughDataForHeuristic()) {
ALOGV("Not enough data");
@@ -196,9 +196,7 @@
const auto refreshRate = Fps::fromPeriodNsecs(*averageFrameTime);
const bool refreshRateConsistent = mRefreshRateHistory.add(refreshRate, now);
if (refreshRateConsistent) {
- const auto knownRefreshRate =
- sRefreshRateConfigs->findClosestKnownFrameRate(refreshRate);
-
+ const auto knownRefreshRate = refreshRateConfigs.findClosestKnownFrameRate(refreshRate);
// To avoid oscillation, use the last calculated refresh rate if it is
// close enough
if (std::abs(mLastRefreshRate.calculated.getValue() - refreshRate.getValue()) >
@@ -220,7 +218,8 @@
: std::nullopt;
}
-LayerInfo::LayerVote LayerInfo::getRefreshRateVote(nsecs_t now) {
+LayerInfo::LayerVote LayerInfo::getRefreshRateVote(const RefreshRateConfigs& refreshRateConfigs,
+ nsecs_t now) {
if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
return mLayerVote;
@@ -247,7 +246,7 @@
clearHistory(now);
}
- auto refreshRate = calculateRefreshRateIfPossible(now);
+ auto refreshRate = calculateRefreshRateIfPossible(refreshRateConfigs, now);
if (refreshRate.has_value()) {
ALOGV("%s calculated refresh rate: %s", mName.c_str(), to_string(*refreshRate).c_str());
return {LayerHistory::LayerVoteType::Heuristic, refreshRate.value()};
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 34cc389..ce9783c 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -122,10 +122,6 @@
static void setTraceEnabled(bool enabled) { sTraceEnabled = enabled; }
- static void setRefreshRateConfigs(const RefreshRateConfigs& refreshRateConfigs) {
- sRefreshRateConfigs = &refreshRateConfigs;
- }
-
LayerInfo(const std::string& name, uid_t ownerUid, LayerHistory::LayerVoteType defaultVote);
LayerInfo(const LayerInfo&) = delete;
@@ -161,7 +157,7 @@
uid_t getOwnerUid() const { return mOwnerUid; }
- LayerVote getRefreshRateVote(nsecs_t now);
+ LayerVote getRefreshRateVote(const RefreshRateConfigs&, nsecs_t now);
// Return the last updated time. If the present time is farther in the future than the
// updated time, the updated time is the present time.
@@ -263,7 +259,7 @@
bool isFrequent(nsecs_t now) const;
bool isAnimating(nsecs_t now) const;
bool hasEnoughDataForHeuristic() const;
- std::optional<Fps> calculateRefreshRateIfPossible(nsecs_t now);
+ std::optional<Fps> calculateRefreshRateIfPossible(const RefreshRateConfigs&, nsecs_t now);
std::optional<nsecs_t> calculateAverageFrameTime() const;
bool isFrameTimeValid(const FrameTimeData&) const;
@@ -300,7 +296,6 @@
mutable std::unordered_map<LayerHistory::LayerVoteType, std::string> mTraceTags;
// Shared for all LayerInfo instances
- static const RefreshRateConfigs* sRefreshRateConfigs;
static bool sTraceEnabled;
};
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 0334d70..c38cd68 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -113,7 +113,7 @@
case LayerVoteType::ExplicitExactOrMultiple:
case LayerVoteType::Heuristic:
if (mConfig.frameRateMultipleThreshold != 0 &&
- refreshRate.fps.greaterThanOrEqualWithMargin(
+ refreshRate.getFps().greaterThanOrEqualWithMargin(
Fps(mConfig.frameRateMultipleThreshold)) &&
layer.desiredRefreshRate.lessThanWithMargin(
Fps(mConfig.frameRateMultipleThreshold / 2))) {
@@ -146,8 +146,8 @@
// If the layer wants Max, give higher score to the higher refresh rate
if (layer.vote == LayerVoteType::Max) {
- const auto ratio =
- refreshRate.fps.getValue() / mAppRequestRefreshRates.back()->fps.getValue();
+ const auto ratio = refreshRate.getFps().getValue() /
+ mAppRequestRefreshRates.back()->getFps().getValue();
// use ratio^2 to get a lower score the more we get further from peak
return ratio * ratio;
}
@@ -463,7 +463,7 @@
}
}();
if (globalSignals.touch && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact &&
- bestRefreshRate->fps.lessThanWithMargin(touchRefreshRate.fps)) {
+ bestRefreshRate->getFps().lessThanWithMargin(touchRefreshRate.getFps())) {
setTouchConsidered();
ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
return touchRefreshRate;
@@ -699,8 +699,7 @@
for (const auto& mode : modes) {
const auto modeId = mode->getId();
mRefreshRates.emplace(modeId,
- std::make_unique<RefreshRate>(modeId, mode, mode->getFps(),
- RefreshRate::ConstructorTag(0)));
+ std::make_unique<RefreshRate>(mode, RefreshRate::ConstructorTag(0)));
if (modeId == currentModeId) {
mCurrentRefreshRate = mRefreshRates.at(modeId).get();
}
@@ -793,7 +792,7 @@
bool RefreshRateConfigs::isModeAllowed(DisplayModeId modeId) const {
std::lock_guard lock(mLock);
for (const RefreshRate* refreshRate : mAppRequestRefreshRates) {
- if (refreshRate->modeId == modeId) {
+ if (refreshRate->getModeId() == modeId) {
return true;
}
}
@@ -808,7 +807,7 @@
for (const auto& [type, refreshRate] : mRefreshRates) {
if (shouldAddRefreshRate(*refreshRate)) {
ALOGV("getSortedRefreshRateListLocked: mode %d added to list policy",
- refreshRate->modeId.value());
+ refreshRate->getModeId().value());
outRefreshRates->push_back(refreshRate.get());
}
}
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index dfd1395..4a9a1fd 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -64,25 +64,23 @@
};
public:
- RefreshRate(DisplayModeId modeId, DisplayModePtr mode, Fps fps, ConstructorTag)
- : modeId(modeId), mode(mode), fps(std::move(fps)) {}
+ RefreshRate(DisplayModePtr mode, ConstructorTag) : mode(mode) {}
- DisplayModeId getModeId() const { return modeId; }
+ DisplayModeId getModeId() const { return mode->getId(); }
nsecs_t getVsyncPeriod() const { return mode->getVsyncPeriod(); }
int32_t getModeGroup() const { return mode->getGroup(); }
- std::string getName() const { return to_string(fps); }
- Fps getFps() const { return fps; }
+ std::string getName() const { return to_string(getFps()); }
+ Fps getFps() const { return mode->getFps(); }
+ DisplayModePtr getMode() const { return mode; }
// Checks whether the fps of this RefreshRate struct is within a given min and max refresh
// rate passed in. Margin of error is applied to the boundaries for approximation.
bool inPolicy(Fps minRefreshRate, Fps maxRefreshRate) const {
- return minRefreshRate.lessThanOrEqualWithMargin(fps) &&
- fps.lessThanOrEqualWithMargin(maxRefreshRate);
+ return minRefreshRate.lessThanOrEqualWithMargin(getFps()) &&
+ getFps().lessThanOrEqualWithMargin(maxRefreshRate);
}
- bool operator!=(const RefreshRate& other) const {
- return modeId != other.modeId || mode != other.mode;
- }
+ bool operator!=(const RefreshRate& other) const { return mode != other.mode; }
bool operator<(const RefreshRate& other) const {
return getFps().getValue() < other.getFps().getValue();
@@ -99,10 +97,7 @@
friend RefreshRateConfigs;
friend class RefreshRateConfigsTest;
- const DisplayModeId modeId;
DisplayModePtr mode;
- // Refresh rate in frames per second
- const Fps fps{0.0f};
};
using AllRefreshRatesMapType =
@@ -316,8 +311,6 @@
Config config = {.enableFrameRateOverride = false,
.frameRateMultipleThreshold = 0});
- void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock);
-
// Returns whether switching modes (refresh rate or resolution) is possible.
// TODO(b/158780872): Consider HAL support, and skip frame rate detection if the modes only
// differ in resolution.
@@ -354,6 +347,9 @@
void dump(std::string& result) const EXCLUDES(mLock);
+ RefreshRateConfigs(const RefreshRateConfigs&) = delete;
+ void operator=(const RefreshRateConfigs&) = delete;
+
private:
friend class RefreshRateConfigsTest;
@@ -405,6 +401,8 @@
float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&,
bool isSeamlessSwitch) const REQUIRES(mLock);
+ void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock);
+
// The list of refresh rates, indexed by display modes ID. This may change after this
// object is initialized.
AllRefreshRatesMapType mRefreshRates GUARDED_BY(mLock);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e0b3640..f808981 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -25,7 +25,7 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
#include <system/window.h>
#include <ui/DisplayStatInfo.h>
#include <utils/Timers.h>
@@ -64,6 +64,8 @@
namespace android {
+using gui::WindowInfo;
+
namespace {
std::unique_ptr<scheduler::VSyncTracker> createVSyncTracker() {
@@ -115,16 +117,17 @@
}
};
-Scheduler::Scheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback)
+Scheduler::Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
+ ISchedulerCallback& callback)
: Scheduler(configs, callback,
{.supportKernelTimer = sysprop::support_kernel_idle_timer(false),
.useContentDetection = sysprop::use_content_detection_for_refresh_rate(false)}) {
}
-Scheduler::Scheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback,
- Options options)
+Scheduler::Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
+ ISchedulerCallback& callback, Options options)
: Scheduler(createVsyncSchedule(options.supportKernelTimer), configs, callback,
- createLayerHistory(configs), options) {
+ createLayerHistory(), options) {
using namespace sysprop;
const int setIdleTimerMs = base::GetIntProperty("debug.sf.set_idle_timer_ms"s, 0);
@@ -157,7 +160,8 @@
}
}
-Scheduler::Scheduler(VsyncSchedule schedule, const scheduler::RefreshRateConfigs& configs,
+Scheduler::Scheduler(VsyncSchedule schedule,
+ const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
ISchedulerCallback& schedulerCallback,
std::unique_ptr<LayerHistory> layerHistory, Options options)
: mOptions(options),
@@ -192,9 +196,8 @@
return {std::move(controller), std::move(tracker), std::move(dispatch)};
}
-std::unique_ptr<LayerHistory> Scheduler::createLayerHistory(
- const scheduler::RefreshRateConfigs& configs) {
- return std::make_unique<scheduler::LayerHistory>(configs);
+std::unique_ptr<LayerHistory> Scheduler::createLayerHistory() {
+ return std::make_unique<scheduler::LayerHistory>();
}
std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
@@ -205,11 +208,14 @@
}
std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
- if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
- return std::nullopt;
+ {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ if (!mRefreshRateConfigs->supportsFrameRateOverride()) {
+ return std::nullopt;
+ }
}
- std::lock_guard lock(mFrameRateOverridesMutex);
+ std::lock_guard lock(mFrameRateOverridesLock);
{
const auto iter = mFrameRateOverridesFromBackdoor.find(uid);
if (iter != mFrameRateOverridesFromBackdoor.end()) {
@@ -237,7 +243,8 @@
}
impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback() const {
- if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ if (!mRefreshRateConfigs->supportsFrameRateOverride()) {
return {};
}
@@ -248,14 +255,18 @@
impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
return [this](uid_t uid) {
- nsecs_t basePeriod = mRefreshRateConfigs.getCurrentRefreshRate().getVsyncPeriod();
+ const auto refreshRateConfigs = holdRefreshRateConfigs();
+ nsecs_t basePeriod = refreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
return basePeriod;
}
- const auto divider = scheduler::RefreshRateConfigs::getFrameRateDivider(
- mRefreshRateConfigs.getCurrentRefreshRate().getFps(), *frameRate);
+ const auto divider =
+ scheduler::RefreshRateConfigs::getFrameRateDivider(refreshRateConfigs
+ ->getCurrentRefreshRate()
+ .getFps(),
+ *frameRate);
if (divider <= 1) {
return basePeriod;
}
@@ -341,7 +352,7 @@
void Scheduler::onFrameRateOverridesChanged(ConnectionHandle handle, PhysicalDisplayId displayId) {
std::vector<FrameRateOverride> overrides;
{
- std::lock_guard lock(mFrameRateOverridesMutex);
+ std::lock_guard lock(mFrameRateOverridesLock);
for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
}
@@ -360,23 +371,22 @@
thread->onFrameRateOverridesChanged(displayId, std::move(overrides));
}
-void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
- DisplayModeId modeId, nsecs_t vsyncPeriod) {
+void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
{
std::lock_guard<std::mutex> lock(mFeatureStateLock);
// Cache the last reported modes for primary display.
- mFeatures.cachedModeChangedParams = {handle, displayId, modeId, vsyncPeriod};
+ mFeatures.cachedModeChangedParams = {handle, mode};
// Invalidate content based refresh rate selection so it could be calculated
// again for the new refresh rate.
mFeatures.contentRequirements.clear();
}
- onNonPrimaryDisplayModeChanged(handle, displayId, modeId, vsyncPeriod);
+ onNonPrimaryDisplayModeChanged(handle, mode);
}
void Scheduler::dispatchCachedReportedMode() {
// Check optional fields first.
- if (!mFeatures.modeId.has_value()) {
+ if (!mFeatures.mode) {
ALOGW("No mode ID found, not dispatching cached mode.");
return;
}
@@ -385,32 +395,24 @@
return;
}
- const auto modeId = *mFeatures.modeId;
- const auto vsyncPeriod = mRefreshRateConfigs.getRefreshRateFromModeId(modeId).getVsyncPeriod();
-
// If there is no change from cached mode, there is no need to dispatch an event
- if (modeId == mFeatures.cachedModeChangedParams->modeId &&
- vsyncPeriod == mFeatures.cachedModeChangedParams->vsyncPeriod) {
+ if (mFeatures.mode == mFeatures.cachedModeChangedParams->mode) {
return;
}
- mFeatures.cachedModeChangedParams->modeId = modeId;
- mFeatures.cachedModeChangedParams->vsyncPeriod = vsyncPeriod;
+ mFeatures.cachedModeChangedParams->mode = mFeatures.mode;
onNonPrimaryDisplayModeChanged(mFeatures.cachedModeChangedParams->handle,
- mFeatures.cachedModeChangedParams->displayId,
- mFeatures.cachedModeChangedParams->modeId,
- mFeatures.cachedModeChangedParams->vsyncPeriod);
+ mFeatures.cachedModeChangedParams->mode);
}
-void Scheduler::onNonPrimaryDisplayModeChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
- DisplayModeId modeId, nsecs_t vsyncPeriod) {
+void Scheduler::onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
android::EventThread* thread;
{
std::lock_guard<std::mutex> lock(mConnectionsLock);
RETURN_IF_INVALID_HANDLE(handle);
thread = mConnections[handle].thread.get();
}
- thread->onModeChanged(displayId, modeId, vsyncPeriod);
+ thread->onModeChanged(mode);
}
size_t Scheduler::getEventThreadConnectionCount(ConnectionHandle handle) {
@@ -530,7 +532,11 @@
const nsecs_t last = mLastResyncTime.exchange(now);
if (now - last > kIgnoreDelay) {
- resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().getVsyncPeriod());
+ const auto vsyncPeriod = [&] {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ return mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ }();
+ resyncToHardwareVsync(false, vsyncPeriod);
}
}
@@ -579,10 +585,9 @@
void Scheduler::registerLayer(Layer* layer) {
scheduler::LayerHistory::LayerVoteType voteType;
- if (!mOptions.useContentDetection ||
- layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
+ if (!mOptions.useContentDetection || layer->getWindowType() == WindowInfo::Type::STATUS_BAR) {
voteType = scheduler::LayerHistory::LayerVoteType::NoVote;
- } else if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) {
+ } else if (layer->getWindowType() == WindowInfo::Type::WALLPAPER) {
// Running Wallpaper at Min is considered as part of content detection.
voteType = scheduler::LayerHistory::LayerVoteType::Min;
} else {
@@ -601,9 +606,12 @@
void Scheduler::recordLayerHistory(Layer* layer, nsecs_t presentTime,
LayerHistory::LayerUpdateType updateType) {
- if (mRefreshRateConfigs.canSwitch()) {
- mLayerHistory->record(layer, presentTime, systemTime(), updateType);
+ {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ if (!mRefreshRateConfigs->canSwitch()) return;
}
+
+ mLayerHistory->record(layer, presentTime, systemTime(), updateType);
}
void Scheduler::setModeChangePending(bool pending) {
@@ -611,25 +619,28 @@
}
void Scheduler::chooseRefreshRateForContent() {
- if (!mRefreshRateConfigs.canSwitch()) return;
+ {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ if (!mRefreshRateConfigs->canSwitch()) return;
+ }
ATRACE_CALL();
- scheduler::LayerHistory::Summary summary = mLayerHistory->summarize(systemTime());
+ const auto refreshRateConfigs = holdRefreshRateConfigs();
+ scheduler::LayerHistory::Summary summary =
+ mLayerHistory->summarize(*refreshRateConfigs, systemTime());
scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
- DisplayModeId newModeId;
+ DisplayModePtr newMode;
bool frameRateChanged;
bool frameRateOverridesChanged;
{
std::lock_guard<std::mutex> lock(mFeatureStateLock);
mFeatures.contentRequirements = summary;
- newModeId = calculateRefreshRateModeId(&consideredSignals);
- auto newRefreshRate = mRefreshRateConfigs.getRefreshRateFromModeId(newModeId);
- frameRateOverridesChanged =
- updateFrameRateOverrides(consideredSignals, newRefreshRate.getFps());
+ newMode = calculateRefreshRateModeId(&consideredSignals);
+ frameRateOverridesChanged = updateFrameRateOverrides(consideredSignals, newMode->getFps());
- if (mFeatures.modeId == newModeId) {
+ if (mFeatures.mode == newMode) {
// We don't need to change the display mode, but we might need to send an event
// about a mode change, since it was suppressed due to a previous idleConsidered
if (!consideredSignals.idle) {
@@ -637,12 +648,12 @@
}
frameRateChanged = false;
} else {
- mFeatures.modeId = newModeId;
+ mFeatures.mode = newMode;
frameRateChanged = true;
}
}
if (frameRateChanged) {
- auto newRefreshRate = mRefreshRateConfigs.getRefreshRateFromModeId(newModeId);
+ auto newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newMode->getId());
mSchedulerCallback.changeRefreshRate(newRefreshRate,
consideredSignals.idle ? ModeEvent::None
: ModeEvent::Changed);
@@ -688,7 +699,11 @@
// TODO(145561154): cleanup the kernel idle timer implementation and the refresh rate
// magic number
- const auto& refreshRate = mRefreshRateConfigs.getCurrentRefreshRate();
+ const auto refreshRate = [&] {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ return mRefreshRateConfigs->getCurrentRefreshRate();
+ }();
+
constexpr Fps FPS_THRESHOLD_FOR_KERNEL_TIMER{65.0f};
if (state == TimerState::Reset &&
refreshRate.getFps().greaterThanWithMargin(FPS_THRESHOLD_FOR_KERNEL_TIMER)) {
@@ -740,7 +755,7 @@
mLayerHistory ? mLayerHistory->dump().c_str() : "(no layer history)");
{
- std::lock_guard lock(mFrameRateOverridesMutex);
+ std::lock_guard lock(mFrameRateOverridesLock);
StringAppendF(&result, "Frame Rate Overrides (backdoor): {");
for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
StringAppendF(&result, "[uid: %d frameRate: %s], ", uid, to_string(frameRate).c_str());
@@ -766,16 +781,17 @@
bool Scheduler::updateFrameRateOverrides(
scheduler::RefreshRateConfigs::GlobalSignals consideredSignals, Fps displayRefreshRate) {
- if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
+ const auto refreshRateConfigs = holdRefreshRateConfigs();
+ if (!refreshRateConfigs->supportsFrameRateOverride()) {
return false;
}
if (!consideredSignals.idle) {
const auto frameRateOverrides =
- mRefreshRateConfigs.getFrameRateOverrides(mFeatures.contentRequirements,
+ refreshRateConfigs->getFrameRateOverrides(mFeatures.contentRequirements,
displayRefreshRate,
consideredSignals.touch);
- std::lock_guard lock(mFrameRateOverridesMutex);
+ std::lock_guard lock(mFrameRateOverridesLock);
if (!std::equal(mFrameRateOverridesByContent.begin(), mFrameRateOverridesByContent.end(),
frameRateOverrides.begin(), frameRateOverrides.end(),
[](const std::pair<uid_t, Fps>& a, const std::pair<uid_t, Fps>& b) {
@@ -790,33 +806,33 @@
template <class T>
bool Scheduler::handleTimerStateChanged(T* currentState, T newState) {
- DisplayModeId newModeId;
+ DisplayModePtr newMode;
bool refreshRateChanged = false;
bool frameRateOverridesChanged;
scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
+ const auto refreshRateConfigs = holdRefreshRateConfigs();
{
std::lock_guard<std::mutex> lock(mFeatureStateLock);
if (*currentState == newState) {
return false;
}
*currentState = newState;
- newModeId = calculateRefreshRateModeId(&consideredSignals);
- const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromModeId(newModeId);
- frameRateOverridesChanged =
- updateFrameRateOverrides(consideredSignals, newRefreshRate.getFps());
- if (mFeatures.modeId == newModeId) {
+ newMode = calculateRefreshRateModeId(&consideredSignals);
+ frameRateOverridesChanged = updateFrameRateOverrides(consideredSignals, newMode->getFps());
+ if (mFeatures.mode == newMode) {
// We don't need to change the display mode, but we might need to send an event
// about a mode change, since it was suppressed due to a previous idleConsidered
if (!consideredSignals.idle) {
dispatchCachedReportedMode();
}
} else {
- mFeatures.modeId = newModeId;
+ mFeatures.mode = newMode;
refreshRateChanged = true;
}
}
if (refreshRateChanged) {
- const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromModeId(newModeId);
+ const RefreshRate& newRefreshRate =
+ refreshRateConfigs->getRefreshRateFromModeId(newMode->getId());
mSchedulerCallback.changeRefreshRate(newRefreshRate,
consideredSignals.idle ? ModeEvent::None
@@ -828,35 +844,36 @@
return consideredSignals.touch;
}
-DisplayModeId Scheduler::calculateRefreshRateModeId(
+DisplayModePtr Scheduler::calculateRefreshRateModeId(
scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals) {
ATRACE_CALL();
if (consideredSignals) *consideredSignals = {};
+ const auto refreshRateConfigs = holdRefreshRateConfigs();
// If Display Power is not in normal operation we want to be in performance mode. When coming
// back to normal mode, a grace period is given with DisplayPowerTimer.
if (mDisplayPowerTimer &&
(!mFeatures.isDisplayPowerStateNormal ||
mFeatures.displayPowerTimer == TimerState::Reset)) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getModeId();
+ return refreshRateConfigs->getMaxRefreshRateByPolicy().getMode();
}
const bool touchActive = mTouchTimer && mFeatures.touch == TouchState::Active;
const bool idle = mIdleTimer && mFeatures.idleTimer == TimerState::Expired;
- return mRefreshRateConfigs
- .getBestRefreshRate(mFeatures.contentRequirements, {.touch = touchActive, .idle = idle},
- consideredSignals)
- .getModeId();
+ return refreshRateConfigs
+ ->getBestRefreshRate(mFeatures.contentRequirements,
+ {.touch = touchActive, .idle = idle}, consideredSignals)
+ .getMode();
}
-std::optional<DisplayModeId> Scheduler::getPreferredModeId() {
+DisplayModePtr Scheduler::getPreferredDisplayMode() {
std::lock_guard<std::mutex> lock(mFeatureStateLock);
// Make sure that the default mode ID is first updated, before returned.
- if (mFeatures.modeId.has_value()) {
- mFeatures.modeId = calculateRefreshRateModeId();
+ if (mFeatures.mode) {
+ mFeatures.mode = calculateRefreshRateModeId();
}
- return mFeatures.modeId;
+ return mFeatures.mode;
}
void Scheduler::onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline) {
@@ -892,7 +909,7 @@
}
}
-void Scheduler::onPrimaryDisplayAreaChanged(uint32_t displayArea) {
+void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) {
mLayerHistory->setDisplayArea(displayArea);
}
@@ -901,7 +918,7 @@
return;
}
- std::lock_guard lock(mFrameRateOverridesMutex);
+ std::lock_guard lock(mFrameRateOverridesLock);
if (frameRateOverride.frameRateHz != 0.f) {
mFrameRateOverridesFromBackdoor[frameRateOverride.uid] = Fps(frameRateOverride.frameRateHz);
} else {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 30a3253..4b6905b 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -72,7 +72,7 @@
using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
using ModeEvent = scheduler::RefreshRateConfigEvent;
- Scheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&);
+ Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&);
~Scheduler();
using ConnectionHandle = scheduler::ConnectionHandle;
@@ -87,15 +87,13 @@
sp<EventThreadConnection> getEventConnection(ConnectionHandle);
void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
- void onPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId,
- nsecs_t vsyncPeriod) EXCLUDES(mFeatureStateLock);
- void onNonPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId,
- nsecs_t vsyncPeriod);
+ void onPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr) EXCLUDES(mFeatureStateLock);
+ void onNonPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr);
void onScreenAcquired(ConnectionHandle);
void onScreenReleased(ConnectionHandle);
void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId)
- EXCLUDES(mFrameRateOverridesMutex) EXCLUDES(mConnectionsLock);
+ EXCLUDES(mFrameRateOverridesLock) EXCLUDES(mConnectionsLock);
// Modifies work duration in the event thread.
void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
@@ -116,7 +114,7 @@
// no-op.
// The period is the vsync period from the current display configuration.
void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
- void resync();
+ void resync() EXCLUDES(mRefreshRateConfigsLock);
// Passes a vsync sample to VsyncController. periodFlushed will be true if
// VsyncController detected that the vsync period changed, and false otherwise.
@@ -127,12 +125,13 @@
// Layers are registered on creation, and unregistered when the weak reference expires.
void registerLayer(Layer*);
- void recordLayerHistory(Layer*, nsecs_t presentTime, LayerHistory::LayerUpdateType updateType);
+ void recordLayerHistory(Layer*, nsecs_t presentTime, LayerHistory::LayerUpdateType updateType)
+ EXCLUDES(mRefreshRateConfigsLock);
void setModeChangePending(bool pending);
void deregisterLayer(Layer*);
// Detects content using layer history, and selects a matching refresh rate.
- void chooseRefreshRateForContent();
+ void chooseRefreshRateForContent() EXCLUDES(mRefreshRateConfigsLock);
bool isIdleTimerEnabled() const { return mIdleTimer.has_value(); }
void resetIdleTimer();
@@ -147,7 +146,7 @@
// Returns true if a given vsync timestamp is considered valid vsync
// for a given uid
bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const
- EXCLUDES(mFrameRateOverridesMutex);
+ EXCLUDES(mFrameRateOverridesLock);
std::chrono::steady_clock::time_point getPreviousVsyncFrom(nsecs_t expectedPresentTime) const;
@@ -156,7 +155,7 @@
void dumpVsync(std::string&) const;
// Get the appropriate refresh for current conditions.
- std::optional<DisplayModeId> getPreferredModeId();
+ DisplayModePtr getPreferredDisplayMode();
// Notifies the scheduler about a refresh rate timeline change.
void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
@@ -165,7 +164,7 @@
void onDisplayRefreshed(nsecs_t timestamp);
// Notifies the scheduler when the display size has changed. Called from SF's main thread
- void onPrimaryDisplayAreaChanged(uint32_t displayArea);
+ void onActiveDisplayAreaChanged(uint32_t displayArea);
size_t getEventThreadConnectionCount(ConnectionHandle handle);
@@ -176,9 +175,21 @@
// Stores the preferred refresh rate that an app should run at.
// FrameRateOverride.refreshRateHz == 0 means no preference.
- void setPreferredRefreshRateForUid(FrameRateOverride) EXCLUDES(mFrameRateOverridesMutex);
+ void setPreferredRefreshRateForUid(FrameRateOverride) EXCLUDES(mFrameRateOverridesLock);
// Retrieves the overridden refresh rate for a given uid.
- std::optional<Fps> getFrameRateOverride(uid_t uid) const EXCLUDES(mFrameRateOverridesMutex);
+ std::optional<Fps> getFrameRateOverride(uid_t uid) const
+ EXCLUDES(mRefreshRateConfigsLock, mFrameRateOverridesLock);
+
+ void setRefreshRateConfigs(std::shared_ptr<scheduler::RefreshRateConfigs> refreshRateConfigs)
+ EXCLUDES(mRefreshRateConfigsLock) {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ mRefreshRateConfigs = std::move(refreshRateConfigs);
+ }
+
+ nsecs_t getVsyncPeriodFromRefreshRateConfigs() const EXCLUDES(mRefreshRateConfigsLock) {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ return mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ }
private:
friend class TestableScheduler;
@@ -203,14 +214,14 @@
};
// Unlike the testing constructor, this creates the VsyncSchedule, LayerHistory, and timers.
- Scheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&, Options);
+ Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&, Options);
// Used by tests to inject mocks.
- Scheduler(VsyncSchedule, const scheduler::RefreshRateConfigs&, ISchedulerCallback&,
- std::unique_ptr<LayerHistory>, Options);
+ Scheduler(VsyncSchedule, const std::shared_ptr<scheduler::RefreshRateConfigs>&,
+ ISchedulerCallback&, std::unique_ptr<LayerHistory>, Options);
static VsyncSchedule createVsyncSchedule(bool supportKernelIdleTimer);
- static std::unique_ptr<LayerHistory> createLayerHistory(const scheduler::RefreshRateConfigs&);
+ static std::unique_ptr<LayerHistory> createLayerHistory();
// Create a connection on the given EventThread.
ConnectionHandle createConnection(std::unique_ptr<EventThread>);
@@ -218,7 +229,7 @@
EventThread*, ISurfaceComposer::EventRegistrationFlags eventRegistration = {});
// Update feature state machine to given state when corresponding timer resets or expires.
- void kernelIdleTimerCallback(TimerState);
+ void kernelIdleTimerCallback(TimerState) EXCLUDES(mRefreshRateConfigsLock);
void idleTimerCallback(TimerState);
void touchTimerCallback(TimerState);
void displayPowerTimerCallback(TimerState);
@@ -232,18 +243,25 @@
// This function checks whether individual features that are affecting the refresh rate
// selection were initialized, prioritizes them, and calculates the DisplayModeId
// for the suggested refresh rate.
- DisplayModeId calculateRefreshRateModeId(
+ DisplayModePtr calculateRefreshRateModeId(
scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr)
REQUIRES(mFeatureStateLock);
- void dispatchCachedReportedMode() REQUIRES(mFeatureStateLock);
+ void dispatchCachedReportedMode() REQUIRES(mFeatureStateLock) EXCLUDES(mRefreshRateConfigsLock);
bool updateFrameRateOverrides(scheduler::RefreshRateConfigs::GlobalSignals consideredSignals,
Fps displayRefreshRate) REQUIRES(mFeatureStateLock)
- EXCLUDES(mFrameRateOverridesMutex);
+ EXCLUDES(mFrameRateOverridesLock);
- impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const;
+ impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const
+ EXCLUDES(mRefreshRateConfigsLock);
impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
+ std::shared_ptr<scheduler::RefreshRateConfigs> holdRefreshRateConfigs() const
+ EXCLUDES(mRefreshRateConfigsLock) {
+ std::scoped_lock lock(mRefreshRateConfigsLock);
+ return mRefreshRateConfigs;
+ }
+
// Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
struct Connection {
sp<EventThreadConnection> connection;
@@ -288,7 +306,7 @@
TouchState touch = TouchState::Inactive;
TimerState displayPowerTimer = TimerState::Expired;
- std::optional<DisplayModeId> modeId;
+ DisplayModePtr mode;
LayerHistory::Summary contentRequirements;
bool isDisplayPowerStateNormal = true;
@@ -296,15 +314,15 @@
// Used to cache the last parameters of onPrimaryDisplayModeChanged
struct ModeChangedParams {
ConnectionHandle handle;
- PhysicalDisplayId displayId;
- DisplayModeId modeId;
- nsecs_t vsyncPeriod;
+ DisplayModePtr mode;
};
std::optional<ModeChangedParams> cachedModeChangedParams;
} mFeatures GUARDED_BY(mFeatureStateLock);
- const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
+ mutable std::mutex mRefreshRateConfigsLock;
+ std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs
+ GUARDED_BY(mRefreshRateConfigsLock);
std::mutex mVsyncTimelineLock;
std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline
@@ -315,14 +333,14 @@
// The frame rate override lists need their own mutex as they are being read
// by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks
- mutable std::mutex mFrameRateOverridesMutex;
+ mutable std::mutex mFrameRateOverridesLock;
// mappings between a UID and a preferred refresh rate that this app would
// run at.
scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesByContent
- GUARDED_BY(mFrameRateOverridesMutex);
+ GUARDED_BY(mFrameRateOverridesLock);
scheduler::RefreshRateConfigs::UidToFrameRateOverride mFrameRateOverridesFromBackdoor
- GUARDED_BY(mFrameRateOverridesMutex);
+ GUARDED_BY(mFrameRateOverridesLock);
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f44ae71..ed15b3a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -146,6 +146,13 @@
return (expr); \
}()
+#define MAIN_THREAD_GUARD(expr) \
+ [&] { \
+ LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \
+ MainThreadScopedGuard lock(SF_MAIN_THREAD); \
+ return (expr); \
+ }()
+
#undef NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS \
_Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"")
@@ -160,6 +167,7 @@
using android::hardware::power::Boost;
using base::StringAppendF;
+using gui::WindowInfo;
using ui::ColorMode;
using ui::Dataspace;
using ui::DisplayPrimaries;
@@ -632,9 +640,7 @@
mVirtualDisplayIdGenerators.gpu.releaseId(*id);
}
-std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIds() const {
- Mutex::Autolock lock(mStateLock);
-
+std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
const auto internalDisplayId = getInternalDisplayIdLocked();
if (!internalDisplayId) {
return {};
@@ -728,7 +734,7 @@
mBootStage = BootStage::FINISHED;
if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
- enableRefreshRateOverlay(true);
+ ON_MAIN_THREAD(enableRefreshRateOverlay(true));
}
}));
}
@@ -792,6 +798,8 @@
? renderengine::RenderEngine::ContextPriority::REALTIME
: renderengine::RenderEngine::ContextPriority::MEDIUM)
.build()));
+ mMaxRenderTargetSize =
+ std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
// Set SF main policy after initializing RenderEngine which has its own policy.
if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
@@ -837,7 +845,7 @@
}
}
- getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
+ onActiveDisplaySizeChanged(display);
// Inform native graphics APIs whether the present timestamp is supported:
@@ -879,14 +887,6 @@
}
}
-size_t SurfaceFlinger::getMaxTextureSize() const {
- return getRenderEngine().getMaxTextureSize();
-}
-
-size_t SurfaceFlinger::getMaxViewportDims() const {
- return getRenderEngine().getMaxViewportDims();
-}
-
// ----------------------------------------------------------------------------
bool SurfaceFlinger::authenticateSurfaceTexture(
@@ -1075,36 +1075,28 @@
void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
ATRACE_CALL();
- auto refreshRate = mRefreshRateConfigs->getRefreshRateFromModeId(info.modeId);
- ALOGV("%s(%s)", __func__, refreshRate.getName().c_str());
- std::lock_guard<std::mutex> lock(mActiveModeLock);
- if (mDesiredActiveModeChanged) {
- // If a mode change is pending, just cache the latest request in mDesiredActiveMode
- const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event;
- mDesiredActiveMode = info;
- mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig;
- } else {
- // Check if we are already at the desired mode
- const auto display = getDefaultDisplayDeviceLocked();
- if (!display || display->getActiveMode()->getId() == refreshRate.getModeId()) {
- return;
- }
+ if (!info.mode) {
+ ALOGW("requested display mode is null");
+ return;
+ }
+ auto display = getDisplayDeviceLocked(info.mode->getPhysicalDisplayId());
+ if (!display) {
+ ALOGW("%s: display is no longer valid", __func__);
+ return;
+ }
- // Initiate a mode change.
- mDesiredActiveModeChanged = true;
- mDesiredActiveMode = info;
-
+ if (display->setDesiredActiveMode(info)) {
// This will trigger HWC refresh without resetting the idle timer.
repaintEverythingForHWC();
// Start receiving vsync samples now, so that we can detect a period
// switch.
- mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, info.mode->getVsyncPeriod());
// As we called to set period, we will call to onRefreshRateChangeCompleted once
// VsyncController model is locked.
modulateVsync(&VsyncModulator::onRefreshRateChangeInitiated);
- updatePhaseConfiguration(refreshRate.getFps());
+ updatePhaseConfiguration(info.mode->getFps());
mScheduler->setModeChangePending(true);
}
}
@@ -1138,7 +1130,7 @@
const auto fps = mode->getFps();
// Keep the old switching type.
const auto allowGroupSwitching =
- mRefreshRateConfigs->getCurrentPolicy().allowGroupSwitching;
+ display->refreshRateConfigs().getCurrentPolicy().allowGroupSwitching;
const scheduler::RefreshRateConfigs::Policy policy{mode->getId(),
allowGroupSwitching,
{fps, fps}};
@@ -1158,63 +1150,49 @@
return;
}
- const auto upcomingMode = display->getMode(mUpcomingActiveMode.modeId);
- if (!upcomingMode) {
- ALOGW("Upcoming active mode is no longer supported. Mode ID = %d",
- mUpcomingActiveMode.modeId.value());
- // TODO(b/159590486) Handle the error better. Some parts of SurfaceFlinger may
- // have been already updated with the upcoming active mode.
+ const auto upcomingModeInfo = MAIN_THREAD_GUARD(display->getUpcomingActiveMode());
+ if (!upcomingModeInfo.mode) {
+ // There is no pending mode change. This can happen if the active
+ // display changed and the mode change happened on a different display.
return;
}
- if (display->getActiveMode()->getSize() != upcomingMode->getSize()) {
+ if (display->getActiveMode()->getSize() != upcomingModeInfo.mode->getSize()) {
auto& state = mCurrentState.displays.editValueFor(display->getDisplayToken());
// We need to generate new sequenceId in order to recreate the display (and this
// way the framebuffer).
state.sequenceId = DisplayDeviceState{}.sequenceId;
- state.physical->activeMode = upcomingMode;
+ state.physical->activeMode = upcomingModeInfo.mode;
processDisplayChangesLocked();
// processDisplayChangesLocked will update all necessary components so we're done here.
return;
}
- std::lock_guard<std::mutex> lock(mActiveModeLock);
- mRefreshRateConfigs->setCurrentModeId(mUpcomingActiveMode.modeId);
- display->setActiveMode(mUpcomingActiveMode.modeId);
+ // We just created this display so we can call even if we are not on
+ // the main thread
+ MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ display->setActiveMode(upcomingModeInfo.mode->getId());
- const Fps refreshRate = upcomingMode->getFps();
-
+ const Fps refreshRate = upcomingModeInfo.mode->getFps();
mRefreshRateStats->setRefreshRate(refreshRate);
-
updatePhaseConfiguration(refreshRate);
- ATRACE_INT("ActiveConfigFPS", refreshRate.getValue());
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(upcomingMode->getFps());
- }
-
- if (mUpcomingActiveMode.event != Scheduler::ModeEvent::None) {
- const nsecs_t vsyncPeriod = refreshRate.getPeriodNsecs();
- const auto physicalId = display->getPhysicalId();
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, physicalId,
- mUpcomingActiveMode.modeId, vsyncPeriod);
+ if (upcomingModeInfo.event != Scheduler::ModeEvent::None) {
+ mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, upcomingModeInfo.mode);
}
}
-void SurfaceFlinger::clearDesiredActiveModeState() {
- std::lock_guard<std::mutex> lock(mActiveModeLock);
- mDesiredActiveMode.event = Scheduler::ModeEvent::None;
- mDesiredActiveModeChanged = false;
- mScheduler->setModeChangePending(false);
+void SurfaceFlinger::clearDesiredActiveModeState(const sp<DisplayDevice>& display) {
+ display->clearDesiredActiveModeState();
+ if (isDisplayActiveLocked(display)) {
+ mScheduler->setModeChangePending(false);
+ }
}
-void SurfaceFlinger::desiredActiveModeChangeDone() {
- const auto modeId = getDesiredActiveMode()->modeId;
-
- clearDesiredActiveModeState();
-
- const auto refreshRate = getDefaultDisplayDeviceLocked()->getMode(modeId)->getFps();
+void SurfaceFlinger::desiredActiveModeChangeDone(const sp<DisplayDevice>& display) {
+ const auto refreshRate = display->getDesiredActiveMode()->mode->getFps();
+ clearDesiredActiveModeState(display);
mScheduler->resyncToHardwareVsync(true, refreshRate.getPeriodNsecs());
updatePhaseConfiguration(refreshRate);
}
@@ -1222,63 +1200,75 @@
void SurfaceFlinger::performSetActiveMode() {
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
- // Store the local variable to release the lock.
- const auto desiredActiveMode = getDesiredActiveMode();
- if (!desiredActiveMode) {
- // No desired active mode pending to be applied
- return;
+
+ for (const auto& iter : mDisplays) {
+ const auto& display = iter.second;
+ if (!display || !display->isInternal()) {
+ continue;
+ }
+
+ // Store the local variable to release the lock.
+ const auto desiredActiveMode = display->getDesiredActiveMode();
+ if (!desiredActiveMode) {
+ // No desired active mode pending to be applied
+ continue;
+ }
+
+ if (!isDisplayActiveLocked(display)) {
+ // display is no longer the active display, so abort the mode change
+ clearDesiredActiveModeState(display);
+ continue;
+ }
+
+ const auto desiredMode = display->getMode(desiredActiveMode->mode->getId());
+ if (!desiredMode) {
+ ALOGW("Desired display mode is no longer supported. Mode ID = %d",
+ desiredActiveMode->mode->getId().value());
+ clearDesiredActiveModeState(display);
+ continue;
+ }
+
+ const auto refreshRate = desiredMode->getFps();
+ ALOGV("%s changing active mode to %d(%s) for display %s", __func__,
+ desiredMode->getId().value(), to_string(refreshRate).c_str(),
+ to_string(display->getId()).c_str());
+
+ if (display->getActiveMode()->getId() == desiredActiveMode->mode->getId()) {
+ // display is not valid or we are already in the requested mode
+ // on both cases there is nothing left to do
+ desiredActiveModeChangeDone(display);
+ continue;
+ }
+
+ // Desired active mode was set, it is different than the mode currently in use, however
+ // allowed modes might have changed by the time we process the refresh.
+ // Make sure the desired mode is still allowed
+ const auto displayModeAllowed =
+ display->refreshRateConfigs().isModeAllowed(desiredActiveMode->mode->getId());
+ if (!displayModeAllowed) {
+ desiredActiveModeChangeDone(display);
+ continue;
+ }
+
+ // TODO(b/142753666) use constrains
+ hal::VsyncPeriodChangeConstraints constraints;
+ constraints.desiredTimeNanos = systemTime();
+ constraints.seamlessRequired = false;
+ hal::VsyncPeriodChangeTimeline outTimeline;
+
+ const auto status = MAIN_THREAD_GUARD(
+ display->initiateModeChange(*desiredActiveMode, constraints, &outTimeline));
+ if (status != NO_ERROR) {
+ // initiateModeChange may fail if a hotplug event is just about
+ // to be sent. We just log the error in this case.
+ ALOGW("initiateModeChange failed: %d", status);
+ continue;
+ }
+ mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
+
+ // Scheduler will submit an empty frame to HWC if needed.
+ mSetActiveModePending = true;
}
-
- const auto display = getDefaultDisplayDeviceLocked();
- const auto desiredMode = display->getMode(desiredActiveMode->modeId);
- if (!desiredMode) {
- ALOGW("Desired display mode is no longer supported. Mode ID = %d",
- desiredActiveMode->modeId.value());
- clearDesiredActiveModeState();
- return;
- }
- const auto refreshRate = desiredMode->getFps();
- ALOGV("%s changing active mode to %d(%s)", __FUNCTION__, desiredMode->getId().value(),
- to_string(refreshRate).c_str());
-
- if (!display || display->getActiveMode()->getId() == desiredActiveMode->modeId) {
- // display is not valid or we are already in the requested mode
- // on both cases there is nothing left to do
- desiredActiveModeChangeDone();
- return;
- }
-
- // Desired active mode was set, it is different than the mode currently in use, however
- // allowed modes might have changed by the time we process the refresh.
- // Make sure the desired mode is still allowed
- if (!isDisplayModeAllowed(desiredActiveMode->modeId)) {
- desiredActiveModeChangeDone();
- return;
- }
-
- mUpcomingActiveMode = *desiredActiveMode;
-
- ATRACE_INT("ActiveModeFPS_HWC", refreshRate.getValue());
-
- // TODO(b/142753666) use constrains
- hal::VsyncPeriodChangeConstraints constraints;
- constraints.desiredTimeNanos = systemTime();
- constraints.seamlessRequired = false;
-
- hal::VsyncPeriodChangeTimeline outTimeline;
- const auto status =
- display->initiateModeChange(mUpcomingActiveMode.modeId, constraints, &outTimeline);
- if (status != NO_ERROR) {
- // initiateModeChange may fail if a hotplug event is just about
- // to be sent. We just log the error in this case.
- ALOGW("initiateModeChange failed: %d", status);
- return;
- }
-
- mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
-
- // Scheduler will submit an empty frame to HWC if needed.
- mSetActiveModePending = true;
}
void SurfaceFlinger::disableExpensiveRendering() {
@@ -1717,10 +1707,10 @@
ATRACE_CALL();
Mutex::Autolock lock(mStateLock);
-
- if (const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId)) {
- auto token = getPhysicalDisplayTokenLocked(*displayId);
- auto display = getDisplayDeviceLocked(token);
+ const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
+ if (displayId) {
+ const auto token = getPhysicalDisplayTokenLocked(*displayId);
+ const auto display = getDisplayDeviceLocked(token);
display->onVsync(timestamp);
}
@@ -1728,8 +1718,10 @@
return;
}
- if (hwcDisplayId != getHwComposer().getInternalHwcDisplayId()) {
- // For now, we don't do anything with external display vsyncs.
+ const bool isActiveDisplay =
+ displayId && getPhysicalDisplayTokenLocked(*displayId) == mActiveDisplayToken;
+ if (!isActiveDisplay) {
+ // For now, we don't do anything with non active display vsyncs.
return;
}
@@ -1745,10 +1737,6 @@
*compositorTiming = getBE().mCompositorTiming;
}
-bool SurfaceFlinger::isDisplayModeAllowed(DisplayModeId modeId) const {
- return mRefreshRateConfigs->isModeAllowed(modeId);
-}
-
void SurfaceFlinger::changeRefreshRateLocked(const RefreshRate& refreshRate,
Scheduler::ModeEvent event) {
const auto display = getDefaultDisplayDeviceLocked();
@@ -1758,13 +1746,13 @@
ATRACE_CALL();
// Don't do any updating if the current fps is the same as the new one.
- if (!isDisplayModeAllowed(refreshRate.getModeId())) {
+ if (!display->refreshRateConfigs().isModeAllowed(refreshRate.getModeId())) {
ALOGV("Skipping mode %d as it is not part of allowed modes",
refreshRate.getModeId().value());
return;
}
- setDesiredActiveMode({refreshRate.getModeId(), event});
+ setDesiredActiveMode({refreshRate.getMode(), event});
}
void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,
@@ -1962,8 +1950,13 @@
}
if (mRefreshRateOverlaySpinner) {
- if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
- mRefreshRateOverlay->onInvalidate();
+ if (Mutex::Autolock lock(mStateLock);
+ const auto display = getDefaultDisplayDeviceLocked()) {
+ if (display) {
+ display->onInvalidate();
+ } else {
+ ALOGW("%s: default display is null", __func__);
+ }
}
}
@@ -2338,7 +2331,7 @@
mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence);
mTransactionCallbackInvoker.sendCallbacks();
- if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON &&
+ if (display && display->isInternal() && display->getPowerMode() == hal::PowerMode::ON &&
mPreviousPresentFences[0].fenceTime->isValid()) {
mScheduler->addPresentFence(mPreviousPresentFences[0].fenceTime);
}
@@ -2475,7 +2468,6 @@
// We call getTransactionFlags(), which will also clear the flags,
// with mStateLock held to guarantee that mCurrentState won't change
// until the transaction is committed.
-
modulateVsync(&VsyncModulator::onTransactionCommit);
transactionFlags = getTransactionFlags(eTransactionMask);
handleTransactionLocked(transactionFlags);
@@ -2527,6 +2519,7 @@
for (const auto& hwcMode : hwcModes) {
newModes.push_back(DisplayMode::Builder(hwcMode.hwcId)
.setId(DisplayModeId{nextModeId++})
+ .setPhysicalDisplayId(displayId)
.setWidth(hwcMode.width)
.setHeight(hwcMode.height)
.setVsyncPeriod(hwcMode.vsyncPeriod)
@@ -2588,11 +2581,6 @@
sp<IBinder> token = new BBinder();
mCurrentState.displays.add(token, state);
mPhysicalDisplayTokens.emplace(displayId, std::move(token));
-
- if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
- initScheduler(state);
- }
-
mInterceptor->saveDisplayCreation(state);
} else {
ALOGV("Recreating display %s", to_string(displayId).c_str());
@@ -2647,6 +2635,14 @@
if (const auto& physical = state.physical) {
creationArgs.connectionType = physical->type;
creationArgs.supportedModes = physical->supportedModes;
+ creationArgs.activeModeId = physical->activeMode->getId();
+ scheduler::RefreshRateConfigs::Config config =
+ {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
+ .frameRateMultipleThreshold =
+ base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};
+ creationArgs.refreshRateConfigs =
+ std::make_shared<scheduler::RefreshRateConfigs>(creationArgs.supportedModes,
+ creationArgs.activeModeId, config);
}
if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
@@ -2703,7 +2699,7 @@
RenderIntent::COLORIMETRIC,
Dataspace::UNKNOWN});
if (!state.isVirtual()) {
- display->setActiveMode(state.physical->activeMode->getId());
+ MAIN_THREAD_GUARD(display->setActiveMode(state.physical->activeMode->getId()));
display->setDeviceProductInfo(state.physical->deviceProductInfo);
}
@@ -2785,14 +2781,12 @@
const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay),
state, displaySurface, producer);
mDisplays.emplace(displayToken, display);
+ if (display->isPrimary()) {
+ initScheduler(display);
+ }
if (!state.isVirtual()) {
dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
}
-
- if (display->isPrimary()) {
- mScheduler->onPrimaryDisplayAreaChanged(display->getWidth() * display->getHeight());
- getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
- }
}
void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
@@ -2857,16 +2851,7 @@
// TODO(b/175678251) Call a listener instead.
if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
- mRefreshRateConfigs->updateDisplayModes(currentState.physical->supportedModes,
- currentState.physical->activeMode->getId());
- mVsyncConfiguration->reset();
- const Fps refreshRate = currentState.physical->activeMode->getFps();
- updatePhaseConfiguration(refreshRate);
- mRefreshRateStats->setRefreshRate(refreshRate);
-
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->reset();
- }
+ updateInternalDisplayVsyncLocked(display);
}
}
return;
@@ -2876,6 +2861,9 @@
if (currentState.layerStack != drawingState.layerStack) {
display->setLayerStack(currentState.layerStack);
}
+ if (currentState.flags != drawingState.flags) {
+ display->setFlags(currentState.flags);
+ }
if ((currentState.orientation != drawingState.orientation) ||
(currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) ||
(currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
@@ -2889,16 +2877,18 @@
currentState.height != drawingState.height) {
display->setDisplaySize(currentState.width, currentState.height);
- if (display->isPrimary()) {
- mScheduler->onPrimaryDisplayAreaChanged(currentState.width * currentState.height);
- }
-
- if (mRefreshRateOverlay) {
- mRefreshRateOverlay->setViewport(display->getSize());
+ if (isDisplayActiveLocked(display)) {
+ onActiveDisplaySizeChanged(display);
}
}
}
}
+void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay) {
+ mVsyncConfiguration->reset();
+ const Fps refreshRate = activeDisplay->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ updatePhaseConfiguration(refreshRate);
+ mRefreshRateStats->setRefreshRate(refreshRate);
+}
void SurfaceFlinger::processDisplayChangesLocked() {
// here we take advantage of Vector's copy-on-write semantics to
@@ -3080,22 +3070,13 @@
}
void SurfaceFlinger::updateInputWindowInfo() {
- std::vector<InputWindowInfo> inputInfos;
+ std::vector<WindowInfo> inputInfos;
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (!layer->needsInputInfo()) return;
- sp<DisplayDevice> display;
- if (enablePerWindowInputRotation()) {
- for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
- const auto& displayDevice = pair.second;
- if (!displayDevice->getCompositionDisplay()
- ->belongsInOutput(layer->getLayerStack(),
- layer->getPrimaryDisplayOnly())) {
- continue;
- }
- display = displayDevice;
- }
- }
+ sp<DisplayDevice> display = enablePerWindowInputRotation()
+ ? ON_MAIN_THREAD(getDisplayWithInputByLayer(layer))
+ : nullptr;
// When calculating the screen bounds we ignore the transparent region since it may
// result in an unwanted offset.
inputInfos.push_back(layer->fillInputInfo(display));
@@ -3135,24 +3116,16 @@
mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
}
-void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
+void SurfaceFlinger::initScheduler(const sp<DisplayDevice>& display) {
if (mScheduler) {
- // In practice it's not allowed to hotplug in/out the primary display once it's been
- // connected during startup, but some tests do it, so just warn and return.
- ALOGW("Can't re-init scheduler");
+ // If the scheduler is already initialized, this means that we received
+ // a hotplug(connected) on the primary display. In that case we should
+ // update the scheduler with the most recent display information.
+ ALOGW("Scheduler already initialized, updating instead");
+ mScheduler->setRefreshRateConfigs(display->holdRefreshRateConfigs());
return;
}
- const auto displayId = displayState.physical->id;
- scheduler::RefreshRateConfigs::Config config =
- {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
- .frameRateMultipleThreshold =
- base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};
- mRefreshRateConfigs =
- std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
- displayState.physical->activeMode
- ->getId(),
- config);
- const auto currRefreshRate = displayState.physical->activeMode->getFps();
+ const auto currRefreshRate = display->getActiveMode()->getFps();
mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
hal::PowerMode::OFF);
@@ -3160,7 +3133,7 @@
mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());
// start the EventThread
- mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
+ mScheduler = getFactory().createScheduler(display->holdRefreshRateConfigs(), *this);
const auto configs = mVsyncConfiguration->getCurrentConfigs();
const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
mAppConnectionHandle =
@@ -3189,9 +3162,7 @@
// This is a bit hacky, but this avoids a back-pointer into the main SF
// classes from EventThread, and there should be no run-time binder cost
// anyway since there are no connected apps at this point.
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, displayId,
- displayState.physical->activeMode->getId(),
- vsyncPeriod);
+ mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, display->getActiveMode());
static auto ignorePresentFences =
base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false);
mScheduler->setIgnorePresentFences(
@@ -3598,7 +3569,7 @@
sp<Layer> layer = nullptr;
if (s.surface) {
- layer = fromHandleLocked(s.surface).promote();
+ layer = fromHandle(s.surface).promote();
} else if (s.hasBufferChanges()) {
ALOGW("Transaction with buffer, but no Layer?");
continue;
@@ -3765,7 +3736,7 @@
setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
postTime, permissions, listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
- if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
+ if (const auto layer = fromHandle(state.state.surface).promote(); layer) {
mScheduler->recordLayerHistory(layer.get(),
isAutoTimestamp ? 0 : desiredPresentTime,
LayerHistory::LayerUpdateType::AnimationTX);
@@ -3844,6 +3815,12 @@
flags |= eDisplayTransactionNeeded;
}
}
+ if (what & DisplayState::eFlagsChanged) {
+ if (state.flags != s.flags) {
+ state.flags = s.flags;
+ flags |= eDisplayTransactionNeeded;
+ }
+ }
if (what & DisplayState::eDisplayProjectionChanged) {
if (state.orientation != s.orientation) {
state.orientation = s.orientation;
@@ -3920,13 +3897,11 @@
if (what & layer_state_t::eLayerCreated) {
layer = handleLayerCreatedLocked(s.surface);
if (layer) {
- // put the created layer into mLayersByLocalBinderToken.
- mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
flags |= eTransactionNeeded | eTraversalNeeded;
mLayersAdded = true;
}
} else {
- layer = fromHandleLocked(s.surface).promote();
+ layer = fromHandle(s.surface).promote();
}
} else {
// The client may provide us a null handle. Treat it as if the layer was removed.
@@ -4104,10 +4079,10 @@
}
if (what & layer_state_t::eInputInfoChanged) {
if (privileged) {
- layer->setInputInfo(*s.inputHandle->getInfo());
+ layer->setInputInfo(*s.windowInfoHandle->getInfo());
flags |= eTraversalNeeded;
} else {
- ALOGE("Attempt to update InputWindowInfo without permission ACCESS_SURFACE_FLINGER");
+ ALOGE("Attempt to update WindowInfo without permission ACCESS_SURFACE_FLINGER");
}
}
std::optional<nsecs_t> dequeueBufferTimestamp;
@@ -4205,17 +4180,30 @@
}
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
+ bool bufferSizeExceedsLimit = false;
std::shared_ptr<renderengine::ExternalTexture> buffer;
if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
- ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
- buffer = ClientCache::getInstance().get(s.cachedBuffer);
+ bufferSizeExceedsLimit =
+ exceedsMaxRenderTargetSize(s.buffer->getWidth(), s.buffer->getHeight());
+ if (!bufferSizeExceedsLimit) {
+ ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ buffer = ClientCache::getInstance().get(s.cachedBuffer);
+ }
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged && s.buffer != nullptr) {
- buffer = std::make_shared<
- renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
- renderengine::ExternalTexture::Usage::READABLE);
+ bufferSizeExceedsLimit =
+ exceedsMaxRenderTargetSize(s.buffer->getWidth(), s.buffer->getHeight());
+ if (!bufferSizeExceedsLimit) {
+ buffer = std::make_shared<
+ renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
+ renderengine::ExternalTexture::Usage::READABLE);
+ }
}
+ ALOGE_IF(bufferSizeExceedsLimit,
+ "Attempted to create an ExternalTexture for layer %s that exceeds render target size "
+ "limit.",
+ layer->getDebugName());
if (buffer) {
const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
const uint64_t frameNumber = frameNumberChanged
@@ -4254,7 +4242,7 @@
{
Mutex::Autolock _l(mStateLock);
- mirrorFrom = fromHandleLocked(mirrorFromHandle).promote();
+ mirrorFrom = fromHandle(mirrorFromHandle).promote();
if (!mirrorFrom) {
return NAME_NOT_FOUND;
}
@@ -4452,7 +4440,7 @@
setTransactionFlags(eTransactionNeeded);
}
-void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer) {
+void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer) {
Mutex::Autolock lock(mStateLock);
// If a layer has a parent, we allow it to out-live it's handle
// with the idea that the parent holds a reference and will eventually
@@ -4463,17 +4451,7 @@
mCurrentState.layersSortedByZ.remove(layer);
}
markLayerPendingRemovalLocked(layer);
-
- auto it = mLayersByLocalBinderToken.begin();
- while (it != mLayersByLocalBinderToken.end()) {
- if (it->second == layer) {
- mBufferCountTracker.remove(it->first->localBinder());
- it = mLayersByLocalBinderToken.erase(it);
- } else {
- it++;
- }
- }
-
+ mBufferCountTracker.remove(handle);
layer.clear();
}
@@ -4508,7 +4486,8 @@
{}, getpid(), getuid(), 0 /* Undefined transactionId */);
setPowerModeInternal(display, hal::PowerMode::ON);
- const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ const nsecs_t vsyncPeriod =
+ display->refreshRateConfigs().getCurrentRefreshRate().getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(vsyncPeriod);
mDefaultDisplayTransformHint = display->getTransformHint();
// Use phase of 0 since phase is not known.
@@ -4522,6 +4501,26 @@
static_cast<void>(schedule([this]() MAIN_THREAD { onInitializeDisplays(); }));
}
+sp<DisplayDevice> SurfaceFlinger::getDisplayWithInputByLayer(Layer* layer) const {
+ sp<DisplayDevice> display;
+ for (const auto& pair : mDisplays) {
+ const auto& displayDevice = pair.second;
+ if (!displayDevice->receivesInput() ||
+ !displayDevice->getCompositionDisplay()
+ ->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
+ continue;
+ }
+ // Don't return immediately so that we can log duplicates.
+ if (display) {
+ ALOGE("Multiple display devices claim to accept input for the same layerstack: %d",
+ layer->getLayerStack());
+ continue;
+ }
+ display = displayDevice;
+ }
+ return display;
+}
+
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
if (display->isVirtual()) {
ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
@@ -4541,8 +4540,12 @@
if (mInterceptor->isEnabled()) {
mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
- const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ const auto vsyncPeriod = display->refreshRateConfigs().getCurrentRefreshRate().getVsyncPeriod();
if (currentMode == hal::PowerMode::OFF) {
+ const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayToken);
+ if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) {
+ onActiveDisplayChangedLocked(display);
+ }
// Keep uclamp in a separate syscall and set it before changing to RT due to b/190237315.
// We can merge the syscall later.
if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
@@ -4552,7 +4555,7 @@
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
getHwComposer().setPowerMode(displayId, mode);
- if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && mode != hal::PowerMode::DOZE_SUSPEND) {
getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4569,7 +4572,7 @@
if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
}
- if (display->isPrimary() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4583,13 +4586,13 @@
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
- if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
+ if (display->isInternal() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
- if (display->isPrimary()) {
+ if (display->isInternal()) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4599,7 +4602,7 @@
getHwComposer().setPowerMode(displayId, mode);
}
- if (display->isPrimary()) {
+ if (display->isInternal()) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
@@ -4768,8 +4771,6 @@
" present offset: %9" PRId64 " ns\t VSYNC period: %9" PRId64 " ns\n\n",
dispSyncPresentTimeOffset, getVsyncPeriodFromHWC());
- mRefreshRateConfigs->dump(result);
-
StringAppendF(&result, "(mode override by backdoor: %s)\n\n",
mDebugDisplayModeSetByBackdoor ? "yes" : "no");
@@ -5645,51 +5646,39 @@
return NO_ERROR;
}
case 1034: {
- switch (n = data.readInt32()) {
- case 0:
- case 1:
- enableRefreshRateOverlay(static_cast<bool>(n));
- break;
- default: {
- Mutex::Autolock lock(mStateLock);
- reply->writeBool(mRefreshRateOverlay != nullptr);
+ schedule([&] {
+ switch (n = data.readInt32()) {
+ case 0:
+ case 1:
+ ON_MAIN_THREAD(enableRefreshRateOverlay(static_cast<bool>(n)));
+ break;
+ default: {
+ reply->writeBool(ON_MAIN_THREAD(isRefreshRateOverlayEnabled()));
+ }
}
- }
+ }).get();
return NO_ERROR;
}
case 1035: {
const int modeId = data.readInt32();
- mDebugDisplayModeSetByBackdoor = false;
- const auto displayId = [&]() -> std::optional<PhysicalDisplayId> {
- uint64_t inputDisplayId = 0;
- if (data.readUint64(&inputDisplayId) == NO_ERROR) {
- const auto token = getPhysicalDisplayToken(
- static_cast<PhysicalDisplayId>(inputDisplayId));
- if (!token) {
- ALOGE("No display with id: %" PRIu64, inputDisplayId);
- return std::nullopt;
- }
-
- return std::make_optional<PhysicalDisplayId>(inputDisplayId);
+ const auto display = [&]() -> sp<IBinder> {
+ uint64_t value;
+ if (data.readUint64(&value) != NO_ERROR) {
+ return getDefaultDisplayDevice()->getDisplayToken().promote();
}
- return getInternalDisplayId();
+ if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(value)) {
+ return getPhysicalDisplayToken(*id);
+ }
+
+ ALOGE("Invalid physical display ID");
+ return nullptr;
}();
- if (!displayId) {
- ALOGE("No display found");
- return NO_ERROR;
- }
-
- status_t result = setActiveMode(getPhysicalDisplayToken(*displayId), modeId);
- if (result != NO_ERROR) {
- return result;
- }
-
- mDebugDisplayModeSetByBackdoor = true;
-
- return NO_ERROR;
+ const status_t result = setActiveMode(display, modeId);
+ mDebugDisplayModeSetByBackdoor = result == NO_ERROR;
+ return result;
}
case 1036: {
if (data.readInt32() > 0) {
@@ -5752,14 +5741,11 @@
std::optional<PhysicalDisplayId> inputId = std::nullopt;
if (uint64_t inputDisplayId;
data.readUint64(&inputDisplayId) == NO_ERROR) {
- const auto token = getPhysicalDisplayToken(
- static_cast<PhysicalDisplayId>(inputDisplayId));
- if (!token) {
+ inputId = DisplayId::fromValue<PhysicalDisplayId>(inputDisplayId);
+ if (!inputId || getPhysicalDisplayToken(*inputId)) {
ALOGE("No display with id: %" PRIu64, inputDisplayId);
return NAME_NOT_FOUND;
}
-
- inputId = std::make_optional<PhysicalDisplayId>(inputDisplayId);
}
{
Mutex::Autolock lock(mStateLock);
@@ -5800,22 +5786,25 @@
static bool updateOverlay =
property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
if (!updateOverlay) return;
- if (Mutex::Autolock lock(mStateLock); !mRefreshRateOverlay) return;
+ if (Mutex::Autolock lock(mStateLock); !isRefreshRateOverlayEnabled()) return;
// Update the overlay on the main thread to avoid race conditions with
// mRefreshRateConfigs->getCurrentRefreshRate()
static_cast<void>(schedule([=] {
- const auto desiredActiveMode = getDesiredActiveMode();
- const std::optional<DisplayModeId> desiredModeId =
- desiredActiveMode ? std::make_optional(desiredActiveMode->modeId) : std::nullopt;
+ const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ if (!display) {
+ ALOGW("%s: default display is null", __func__);
+ return;
+ }
+
+ const auto desiredActiveMode = display->getDesiredActiveMode();
+ const std::optional<DisplayModeId> desiredModeId = desiredActiveMode
+ ? std::make_optional(desiredActiveMode->mode->getId())
+ : std::nullopt;
const bool timerExpired = mKernelIdleTimerEnabled && expired;
- const auto newRefreshRate =
- mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
- if (newRefreshRate) {
- if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
- mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
- }
+
+ if (display->onKernelTimerChanged(desiredModeId, timerExpired)) {
mEventQueue->invalidate();
}
}));
@@ -5828,8 +5817,13 @@
if (!mSupportKernelIdleTimer) {
return;
}
- const KernelIdleTimerAction action = mRefreshRateConfigs->getIdleTimerAction();
+ const auto display = getDefaultDisplayDeviceLocked();
+ if (!display) {
+ ALOGW("%s: default display is null", __func__);
+ return;
+ }
+ const KernelIdleTimerAction action = display->refreshRateConfigs().getIdleTimerAction();
switch (action) {
case KernelIdleTimerAction::TurnOff:
if (mKernelIdleTimerEnabled) {
@@ -6009,7 +6003,7 @@
captureListener);
}
-status_t SurfaceFlinger::captureDisplay(uint64_t displayIdOrLayerStack,
+status_t SurfaceFlinger::captureDisplay(DisplayId displayId,
const sp<IScreenCaptureListener>& captureListener) {
ui::LayerStack layerStack;
wp<const DisplayDevice> displayWeak;
@@ -6017,21 +6011,14 @@
ui::Dataspace dataspace;
{
Mutex::Autolock lock(mStateLock);
- auto display = getDisplayDeviceLocked(PhysicalDisplayId{displayIdOrLayerStack});
- // Fall back to first display whose layer stack matches.
- if (!display) {
- const auto layerStack = static_cast<ui::LayerStack>(displayIdOrLayerStack);
- display = findDisplay(WithLayerStack(layerStack));
- }
-
+ const auto display = getDisplayDeviceLocked(displayId);
if (!display) {
return NAME_NOT_FOUND;
}
- layerStack = display->getLayerStack();
displayWeak = display;
-
+ layerStack = display->getLayerStack();
size = display->getLayerStackSpaceRect().getSize();
dataspace =
@@ -6076,7 +6063,7 @@
{
Mutex::Autolock lock(mStateLock);
- parent = fromHandleLocked(args.layerHandle).promote();
+ parent = fromHandle(args.layerHandle).promote();
if (parent == nullptr || parent->isRemovedFromCurrentState()) {
ALOGE("captureLayers called with an invalid or removed parent");
return NAME_NOT_FOUND;
@@ -6107,7 +6094,7 @@
reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY);
for (const auto& handle : args.excludeHandles) {
- sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
+ sp<Layer> excludeLayer = fromHandle(handle).promote();
if (excludeLayer != nullptr) {
excludeLayers.emplace(excludeLayer);
} else {
@@ -6116,7 +6103,11 @@
}
}
- const auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
+ const auto display =
+ findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
+ return display.getLayerStack() == layerStack;
+ });
+
if (!display) {
return NAME_NOT_FOUND;
}
@@ -6185,6 +6176,13 @@
const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
+ if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
+ ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
+ ") that exceeds render target size limit.",
+ bufferSize.getWidth(), bufferSize.getHeight());
+ return BAD_VALUE;
+ }
+
// Loop over all visible layers to see whether there's any protected layer. A protected layer is
// typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
// A protected layer has no implication on whether it's secure, which is explicitly set by
@@ -6324,7 +6322,6 @@
const auto display = renderArea.getDisplayDevice();
std::vector<Layer*> renderedLayers;
- Region clearRegion = Region::INVALID_REGION;
bool disableBlurs = false;
traverseLayers([&](Layer* layer) {
disableBlurs |= layer->getDrawingState().sidebandStream != nullptr;
@@ -6336,7 +6333,6 @@
renderArea.needsFiltering(),
renderArea.isSecure(),
useProtected,
- clearRegion,
layerStackSpaceRect,
clientCompositionDisplay.outputDataspace,
true, /* realContentIsVisible */
@@ -6374,7 +6370,6 @@
clientCompositionLayerPointers.begin(),
std::pointer_traits<renderengine::LayerSettings*>::pointer_to);
- clientCompositionDisplay.clearRegion = clearRegion;
// Use an empty fence for the buffer fence, since we just created the buffer so
// there is no need for synchronization with the GPU.
base::unique_fd bufferFence;
@@ -6447,78 +6442,55 @@
const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
Mutex::Autolock lock(mStateLock);
- LOG_ALWAYS_FATAL_IF(!display->isPrimary() && overridePolicy,
- "Can only set override policy on the primary display");
- LOG_ALWAYS_FATAL_IF(!policy && !overridePolicy, "Can only clear the override policy");
-
if (mDebugDisplayModeSetByBackdoor) {
// ignore this request as mode is overridden by backdoor
return NO_ERROR;
}
- if (!display->isPrimary()) {
- // TODO(b/144711714): For non-primary displays we should be able to set an active mode
- // as well. For now, just call directly to initiateModeChange but ideally
- // it should go thru setDesiredActiveMode, similar to primary display.
- ALOGV("%s for non-primary display", __func__);
- const auto displayId = display->getPhysicalId();
-
- hal::VsyncPeriodChangeConstraints constraints;
- constraints.desiredTimeNanos = systemTime();
- constraints.seamlessRequired = false;
-
- hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- if (display->initiateModeChange(policy->defaultMode, constraints, &timeline) != NO_ERROR) {
- return BAD_VALUE;
- }
- if (timeline.refreshRequired) {
- repaintEverythingForHWC();
- }
-
- display->setActiveMode(policy->defaultMode);
- const nsecs_t vsyncPeriod = display->getMode(policy->defaultMode)->getVsyncPeriod();
- mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, displayId,
- policy->defaultMode, vsyncPeriod);
- return NO_ERROR;
- }
-
status_t setPolicyResult = overridePolicy
- ? mRefreshRateConfigs->setOverridePolicy(policy)
- : mRefreshRateConfigs->setDisplayManagerPolicy(*policy);
+ ? display->refreshRateConfigs().setOverridePolicy(policy)
+ : display->refreshRateConfigs().setDisplayManagerPolicy(*policy);
if (setPolicyResult < 0) {
return BAD_VALUE;
}
if (setPolicyResult == scheduler::RefreshRateConfigs::CURRENT_POLICY_UNCHANGED) {
return NO_ERROR;
}
- scheduler::RefreshRateConfigs::Policy currentPolicy = mRefreshRateConfigs->getCurrentPolicy();
+
+ scheduler::RefreshRateConfigs::Policy currentPolicy =
+ display->refreshRateConfigs().getCurrentPolicy();
ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
// be depending in this callback.
const auto activeMode = display->getActiveMode();
- const nsecs_t vsyncPeriod = activeMode->getVsyncPeriod();
- const auto physicalId = display->getPhysicalId();
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, physicalId, activeMode->getId(),
- vsyncPeriod);
- toggleKernelIdleTimer();
+ if (isDisplayActiveLocked(display)) {
+ mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ toggleKernelIdleTimer();
+ } else {
+ mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ }
- auto modeId = mScheduler->getPreferredModeId();
- auto preferredRefreshRate = modeId
- ? mRefreshRateConfigs->getRefreshRateFromModeId(*modeId)
- // NOTE: Choose the default mode ID, if Scheduler doesn't have one in mind.
- : mRefreshRateConfigs->getRefreshRateFromModeId(currentPolicy.defaultMode);
+ const DisplayModePtr preferredDisplayMode = [&] {
+ const auto schedulerMode = mScheduler->getPreferredDisplayMode();
+ if (schedulerMode && schedulerMode->getPhysicalDisplayId() == display->getPhysicalId()) {
+ return schedulerMode;
+ }
+
+ return display->getMode(currentPolicy.defaultMode);
+ }();
+
ALOGV("trying to switch to Scheduler preferred mode %d (%s)",
- preferredRefreshRate.getModeId().value(), preferredRefreshRate.getName().c_str());
+ preferredDisplayMode->getId().value(), to_string(preferredDisplayMode->getFps()).c_str());
- if (isDisplayModeAllowed(preferredRefreshRate.getModeId())) {
+ if (display->refreshRateConfigs().isModeAllowed(preferredDisplayMode->getId())) {
ALOGV("switching to Scheduler preferred display mode %d",
- preferredRefreshRate.getModeId().value());
- setDesiredActiveMode({preferredRefreshRate.getModeId(), Scheduler::ModeEvent::Changed});
+ preferredDisplayMode->getId().value());
+ setDesiredActiveMode({preferredDisplayMode, Scheduler::ModeEvent::Changed});
} else {
LOG_ALWAYS_FATAL("Desired display mode not allowed: %d",
- preferredRefreshRate.getModeId().value());
+ preferredDisplayMode->getId().value());
}
return NO_ERROR;
@@ -6578,49 +6550,23 @@
return NAME_NOT_FOUND;
}
- if (display->isPrimary()) {
- scheduler::RefreshRateConfigs::Policy policy =
- mRefreshRateConfigs->getDisplayManagerPolicy();
- *outDefaultMode = policy.defaultMode.value();
- *outAllowGroupSwitching = policy.allowGroupSwitching;
- *outPrimaryRefreshRateMin = policy.primaryRange.min.getValue();
- *outPrimaryRefreshRateMax = policy.primaryRange.max.getValue();
- *outAppRequestRefreshRateMin = policy.appRequestRange.min.getValue();
- *outAppRequestRefreshRateMax = policy.appRequestRange.max.getValue();
- return NO_ERROR;
- } else if (display->isVirtual()) {
+ if (display->isVirtual()) {
return INVALID_OPERATION;
- } else {
- const auto activeMode = display->getActiveMode();
- *outDefaultMode = activeMode->getId().value();
- *outAllowGroupSwitching = false;
- auto vsyncPeriod = activeMode->getVsyncPeriod();
- *outPrimaryRefreshRateMin = Fps::fromPeriodNsecs(vsyncPeriod).getValue();
- *outPrimaryRefreshRateMax = Fps::fromPeriodNsecs(vsyncPeriod).getValue();
- *outAppRequestRefreshRateMin = Fps::fromPeriodNsecs(vsyncPeriod).getValue();
- *outAppRequestRefreshRateMax = Fps::fromPeriodNsecs(vsyncPeriod).getValue();
- return NO_ERROR;
}
+
+ scheduler::RefreshRateConfigs::Policy policy =
+ display->refreshRateConfigs().getDisplayManagerPolicy();
+ *outDefaultMode = policy.defaultMode.value();
+ *outAllowGroupSwitching = policy.allowGroupSwitching;
+ *outPrimaryRefreshRateMin = policy.primaryRange.min.getValue();
+ *outPrimaryRefreshRateMax = policy.primaryRange.max.getValue();
+ *outAppRequestRefreshRateMin = policy.appRequestRange.min.getValue();
+ *outAppRequestRefreshRateMax = policy.appRequestRange.max.getValue();
+ return NO_ERROR;
}
-wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
- Mutex::Autolock _l(mStateLock);
- return fromHandleLocked(handle);
-}
-
-wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) const {
- BBinder* b = nullptr;
- if (handle) {
- b = handle->localBinder();
- }
- if (b == nullptr) {
- return nullptr;
- }
- auto it = mLayersByLocalBinderToken.find(b);
- if (it != mLayersByLocalBinderToken.end()) {
- return it->second;
- }
- return nullptr;
+wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) const {
+ return Layer::fromHandle(handle);
}
void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
@@ -6735,7 +6681,8 @@
// matter for the override policy though, since we set allowGroupSwitching to
// true, so it's not a problem.
scheduler::RefreshRateConfigs::Policy overridePolicy;
- overridePolicy.defaultMode = mRefreshRateConfigs->getDisplayManagerPolicy().defaultMode;
+ overridePolicy.defaultMode =
+ display->refreshRateConfigs().getDisplayManagerPolicy().defaultMode;
overridePolicy.allowGroupSwitching = true;
constexpr bool kOverridePolicy = true;
result = setDesiredDisplayModeSpecsInternal(display, overridePolicy, kOverridePolicy);
@@ -6803,25 +6750,11 @@
}
void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
- static_cast<void>(schedule([=] {
- std::unique_ptr<RefreshRateOverlay> overlay;
- if (enable) {
- overlay = std::make_unique<RefreshRateOverlay>(*this, mRefreshRateOverlaySpinner);
+ for (const auto& [ignored, display] : mDisplays) {
+ if (display->isInternal()) {
+ display->enableRefreshRateOverlay(enable, mRefreshRateOverlaySpinner);
}
-
- {
- Mutex::Autolock lock(mStateLock);
-
- // Destroy the layer of the current overlay, if any, outside the lock.
- mRefreshRateOverlay.swap(overlay);
- if (!mRefreshRateOverlay) return;
-
- if (const auto display = getDefaultDisplayDeviceLocked()) {
- mRefreshRateOverlay->setViewport(display->getSize());
- mRefreshRateOverlay->changeRefreshRate(display->getActiveMode()->getFps());
- }
- }
- }));
+ }
}
status_t SurfaceFlinger::addTransactionTraceListener(
@@ -6849,7 +6782,14 @@
}
status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
- const auto maxSupportedRefreshRate = mRefreshRateConfigs->getSupportedRefreshRateRange().max;
+ const auto maxSupportedRefreshRate = [&] {
+ const auto display = getDefaultDisplayDevice();
+ if (display) {
+ return display->refreshRateConfigs().getSupportedRefreshRateRange().max;
+ }
+ ALOGW("%s: default display is null", __func__);
+ return Fps(60);
+ }();
*buffers = getMaxAcquiredBufferCountForRefreshRate(maxSupportedRefreshRate);
return NO_ERROR;
}
@@ -6860,7 +6800,14 @@
if (frameRateOverride.has_value()) {
return frameRateOverride.value();
}
- return mRefreshRateConfigs->getCurrentRefreshRate().getFps();
+
+ const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ if (display) {
+ return display->refreshRateConfigs().getCurrentRefreshRate().getFps();
+ }
+
+ ALOGW("%s: default display is null", __func__);
+ return Fps(60);
}();
return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
}
@@ -6925,7 +6872,7 @@
sp<Layer> parent;
bool allowAddRoot = state->addToRoot;
if (state->initialParent != nullptr) {
- parent = fromHandleLocked(state->initialParent.promote()).promote();
+ parent = fromHandle(state->initialParent.promote()).promote();
if (parent == nullptr) {
ALOGE("Invalid parent %p", state->initialParent.unsafe_get());
allowAddRoot = false;
@@ -6977,6 +6924,31 @@
mRegionSamplingThread->onCompositionComplete(mEventQueue->nextExpectedInvalidate());
}
+void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay) {
+ mScheduler->onActiveDisplayAreaChanged(activeDisplay->getWidth() * activeDisplay->getHeight());
+ getRenderEngine().onActiveDisplaySizeChanged(activeDisplay->getSize());
+}
+
+void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
+ ATRACE_CALL();
+
+ if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
+ display->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
+ }
+
+ if (!activeDisplay) {
+ ALOGE("%s: activeDisplay is null", __func__);
+ return;
+ }
+ mActiveDisplayToken = activeDisplay->getDisplayToken();
+
+ activeDisplay->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);
+ updateInternalDisplayVsyncLocked(activeDisplay);
+ mScheduler->setModeChangePending(false);
+ mScheduler->setRefreshRateConfigs(activeDisplay->holdRefreshRateConfigs());
+ onActiveDisplaySizeChanged(activeDisplay);
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4fd86af..3967ca8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -327,8 +327,7 @@
// Returns nullptr if the handle does not point to an existing layer.
// Otherwise, returns a weak reference so that callers off the main-thread
// won't accidentally hold onto the last strong reference.
- wp<Layer> fromHandle(const sp<IBinder>& handle);
- wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock);
+ wp<Layer> fromHandle(const sp<IBinder>& handle) const;
// If set, disables reusing client composition buffers. This can be set by
// debug.sf.disable_client_composition_cache
@@ -456,14 +455,7 @@
mCounterByLayerHandle GUARDED_BY(mLock);
};
- struct ActiveModeInfo {
- DisplayModeId modeId;
- Scheduler::ModeEvent event = Scheduler::ModeEvent::None;
-
- bool operator!=(const ActiveModeInfo& other) const {
- return modeId != other.modeId || event != other.event;
- }
- };
+ using ActiveModeInfo = DisplayDevice::ActiveModeInfo;
enum class BootStage {
BOOTLOADER,
@@ -594,7 +586,7 @@
typename Handler = VsyncModulator::VsyncConfigOpt (VsyncModulator::*)(Args...)>
void modulateVsync(Handler handler, Args... args) {
if (const auto config = (*mVsyncModulator.*handler)(args...)) {
- const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ const auto vsyncPeriod = mScheduler->getVsyncPeriodFromRefreshRateConfigs();
setVsyncConfig(*config, vsyncPeriod);
}
}
@@ -613,7 +605,10 @@
sp<ISurfaceComposerClient> createConnection() override;
sp<IBinder> createDisplay(const String8& displayName, bool secure) override;
void destroyDisplay(const sp<IBinder>& displayToken) override;
- std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override;
+ std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override EXCLUDES(mStateLock) {
+ Mutex::Autolock lock(mStateLock);
+ return getPhysicalDisplayIdsLocked();
+ }
sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override;
status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
const Vector<ComposerState>& state,
@@ -631,12 +626,10 @@
sp<IDisplayEventConnection> createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp,
ISurfaceComposer::EventRegistrationFlags eventRegistration = {}) override;
- status_t captureDisplay(const DisplayCaptureArgs& args,
- const sp<IScreenCaptureListener>& captureListener) override;
- status_t captureDisplay(uint64_t displayOrLayerStack,
- const sp<IScreenCaptureListener>& captureListener) override;
- status_t captureLayers(const LayerCaptureArgs& args,
- const sp<IScreenCaptureListener>& captureListener) override;
+
+ status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&) override;
+ status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) override;
+ status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) override;
status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats) override;
status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*)
@@ -751,7 +744,7 @@
// Called when the frame rate override list changed to trigger an event.
void triggerOnFrameRateOverridesChanged() override;
// Toggles the kernel idle timer on or off depending the policy decisions around refresh rates.
- void toggleKernelIdleTimer();
+ void toggleKernelIdleTimer() REQUIRES(mStateLock);
// Keeps track of whether the kernel idle timer is currently enabled, so we don't have to
// make calls to sys prop each time.
bool mKernelIdleTimerEnabled = false;
@@ -780,9 +773,9 @@
// Calls to setActiveMode on the main thread if there is a pending mode change
// that needs to be applied.
void performSetActiveMode() REQUIRES(mStateLock);
- void clearDesiredActiveModeState() REQUIRES(mStateLock) EXCLUDES(mActiveModeLock);
+ void clearDesiredActiveModeState(const sp<DisplayDevice>&) REQUIRES(mStateLock);
// Called when active mode is no longer is progress
- void desiredActiveModeChangeDone() REQUIRES(mStateLock);
+ void desiredActiveModeChangeDone(const sp<DisplayDevice>&) REQUIRES(mStateLock);
// Called on the main thread in response to setPowerMode()
void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode)
REQUIRES(mStateLock);
@@ -815,7 +808,7 @@
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
- void initScheduler(const DisplayDeviceState&) REQUIRES(mStateLock);
+ void initScheduler(const sp<DisplayDevice>& display) REQUIRES(mStateLock);
void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock);
void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod);
@@ -898,7 +891,7 @@
// called when all clients have released all their references to
// this layer meaning it is entirely safe to destroy all
// resources associated to this layer.
- void onHandleDestroyed(sp<Layer>& layer);
+ void onHandleDestroyed(BBinder* handle, sp<Layer>& layer);
void markLayerPendingRemovalLocked(const sp<Layer>& layer);
// add a layer to SurfaceFlinger
@@ -931,8 +924,9 @@
void readPersistentProperties();
- size_t getMaxTextureSize() const;
- size_t getMaxViewportDims() const;
+ bool exceedsMaxRenderTargetSize(uint32_t width, uint32_t height) const {
+ return width > mMaxRenderTargetSize || height > mMaxRenderTargetSize;
+ }
int getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
@@ -954,6 +948,10 @@
sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const
REQUIRES(mStateLock) {
+ return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(id);
+ }
+
+ sp<DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) REQUIRES(mStateLock) {
if (const auto token = getPhysicalDisplayTokenLocked(id)) {
return getDisplayDeviceLocked(token);
}
@@ -965,13 +963,18 @@
}
sp<DisplayDevice> getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) {
+ if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
+ return display;
+ }
+ // The active display is outdated, fall back to the internal display
+ mActiveDisplayToken.clear();
if (const auto token = getInternalDisplayTokenLocked()) {
return getDisplayDeviceLocked(token);
}
return nullptr;
}
- sp<const DisplayDevice> getDefaultDisplayDevice() EXCLUDES(mStateLock) {
+ sp<const DisplayDevice> getDefaultDisplayDevice() const EXCLUDES(mStateLock) {
Mutex::Autolock lock(mStateLock);
return getDefaultDisplayDeviceLocked();
}
@@ -990,10 +993,18 @@
return findDisplay([id](const auto& display) { return display.getId() == id; });
}
+ std::vector<PhysicalDisplayId> getPhysicalDisplayIdsLocked() const REQUIRES(mStateLock);
+
// mark a region of a layer stack dirty. this updates the dirty
// region of all screens presenting this layer stack.
void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
+ sp<DisplayDevice> getDisplayWithInputByLayer(Layer* layer) const REQUIRES(mStateLock);
+
+ bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) REQUIRES(mStateLock) {
+ return display->getDisplayToken() == mActiveDisplayToken;
+ }
+
/*
* H/W composer
*/
@@ -1050,8 +1061,6 @@
// the desired refresh rate.
void changeRefreshRateLocked(const RefreshRate&, Scheduler::ModeEvent) REQUIRES(mStateLock);
- bool isDisplayModeAllowed(DisplayModeId) const REQUIRES(mStateLock);
-
struct FenceWithFenceTime {
sp<Fence> fence = Fence::NO_FENCE;
std::shared_ptr<FenceTime> fenceTime = FenceTime::NO_FENCE;
@@ -1116,6 +1125,10 @@
REQUIRES(mStateLock);
void releaseVirtualDisplay(VirtualDisplayId);
+ void onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) REQUIRES(mStateLock);
+
+ void onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay);
+
/*
* Debugging & dumpsys
*/
@@ -1181,13 +1194,6 @@
/*
* Misc
*/
-
- std::optional<ActiveModeInfo> getDesiredActiveMode() EXCLUDES(mActiveModeLock) {
- std::lock_guard<std::mutex> lock(mActiveModeLock);
- if (mDesiredActiveModeChanged) return mDesiredActiveMode;
- return std::nullopt;
- }
-
std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId displayId)
REQUIRES(mStateLock);
@@ -1195,6 +1201,9 @@
std::chrono::nanoseconds presentLatency);
int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const;
+ void updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay)
+ REQUIRES(mStateLock);
+
sp<StartPropertySetThread> mStartPropertySetThread;
surfaceflinger::Factory& mFactory;
@@ -1282,8 +1291,6 @@
std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal;
} mVirtualDisplayIdGenerators;
- std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
-
// don't use a lock for these, we don't care
int mDebugRegion = 0;
bool mDebugDisableHWC = false;
@@ -1373,6 +1380,9 @@
SurfaceFlingerBE mBE;
std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
+ // mMaxRenderTargetSize is only set once in init() so it doesn't need to be protected by
+ // any mutex.
+ size_t mMaxRenderTargetSize{1};
const std::string mHwcServiceName;
@@ -1391,24 +1401,13 @@
// Optional to defer construction until PhaseConfiguration is created.
sp<VsyncModulator> mVsyncModulator;
- std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
std::atomic<nsecs_t> mExpectedPresentTime = 0;
nsecs_t mScheduledPresentTime = 0;
hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE;
- std::mutex mActiveModeLock;
- // This bit is set once we start setting the mode. We read from this bit during the
- // process. If at the end, this bit is different than mDesiredActiveMode, we restart
- // the process.
- ActiveModeInfo mUpcomingActiveMode; // Always read and written on the main thread.
- // This bit can be set at any point in time when the system wants the new mode.
- ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock);
-
// below flags are set by main thread only
- TracedOrdinal<bool> mDesiredActiveModeChanged
- GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false};
bool mSetActiveModePending = false;
bool mLumaSampling = true;
@@ -1431,8 +1430,7 @@
// This should only be accessed on the main thread.
nsecs_t mFrameStartTime = 0;
- void enableRefreshRateOverlay(bool enable);
- std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay GUARDED_BY(mStateLock);
+ void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock);
// Flag used to set override desired display mode from backdoor
bool mDebugDisplayModeSetByBackdoor = false;
@@ -1487,6 +1485,15 @@
void scheduleRegionSamplingThread();
void notifyRegionSamplingThread();
+
+ bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) {
+ return std::any_of(mDisplays.begin(), mDisplays.end(),
+ [](std::pair<wp<IBinder>, sp<DisplayDevice>> display) {
+ return display.second->isRefreshRateOverlayEnabled();
+ });
+ }
+
+ wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock);
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
index 4a75180..89d1c4d 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
@@ -65,8 +65,9 @@
}
std::unique_ptr<Scheduler> DefaultFactory::createScheduler(
- const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback) {
- return std::make_unique<Scheduler>(configs, callback);
+ const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
+ ISchedulerCallback& callback) {
+ return std::make_unique<Scheduler>(std::move(refreshRateConfigs), callback);
}
sp<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor() {
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
index 24148dd..b8bf2ba 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
@@ -30,8 +30,8 @@
std::unique_ptr<MessageQueue> createMessageQueue() override;
std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
Fps currentRefreshRate) override;
- std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
- ISchedulerCallback&) override;
+ std::unique_ptr<Scheduler> createScheduler(
+ const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&) override;
sp<SurfaceInterceptor> createSurfaceInterceptor() override;
sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override;
sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) override;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 885297f..13c95dd 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -79,8 +79,8 @@
virtual std::unique_ptr<MessageQueue> createMessageQueue() = 0;
virtual std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
Fps currentRefreshRate) = 0;
- virtual std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
- ISchedulerCallback&) = 0;
+ virtual std::unique_ptr<Scheduler> createScheduler(
+ const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&) = 0;
virtual sp<SurfaceInterceptor> createSurfaceInterceptor() = 0;
virtual sp<StartPropertySetThread> createStartPropertySetThread(
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 23ab7c8..9be3abe 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -161,6 +161,7 @@
addDisplaySurfaceLocked(transaction, display.sequenceId, display.surface);
addDisplayLayerStackLocked(transaction, display.sequenceId, display.layerStack);
+ addDisplayFlagsLocked(transaction, display.sequenceId, display.flags);
addDisplaySizeLocked(transaction, display.sequenceId, display.width, display.height);
addDisplayProjectionLocked(transaction, display.sequenceId, toRotationInt(display.orientation),
display.layerStackSpaceRect, display.orientedDisplaySpaceRect);
@@ -183,12 +184,9 @@
return NO_ERROR;
}
-const sp<const Layer> SurfaceInterceptor::getLayer(const wp<const IBinder>& weakHandle) const {
- const sp<const IBinder>& handle(weakHandle.promote());
- const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
- const sp<const Layer> layer(layerHandle->owner.promote());
- // layer could be a nullptr at this point
- return layer;
+const sp<const Layer> SurfaceInterceptor::getLayer(const wp<IBinder>& weakHandle) const {
+ sp<IBinder> handle = weakHandle.promote();
+ return Layer::fromHandle(handle).promote();
}
int32_t SurfaceInterceptor::getLayerId(const sp<const Layer>& layer) const {
@@ -203,12 +201,11 @@
return strongLayer == nullptr ? -1 : getLayerId(strongLayer);
}
-int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<const IBinder>& handle) const {
+int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<IBinder>& handle) const {
if (handle == nullptr) {
return -1;
}
- const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
- const sp<const Layer> layer(layerHandle->owner.promote());
+ const sp<const Layer> layer = Layer::fromHandle(handle).promote();
return layer == nullptr ? -1 : getLayerId(layer);
}
@@ -485,6 +482,9 @@
if (state.what & DisplayState::eLayerStackChanged) {
addDisplayLayerStackLocked(transaction, sequenceId, state.layerStack);
}
+ if (state.what & DisplayState::eFlagsChanged) {
+ addDisplayFlagsLocked(transaction, sequenceId, state.flags);
+ }
if (state.what & DisplayState::eDisplaySizeChanged) {
addDisplaySizeLocked(transaction, sequenceId, state.width, state.height);
}
@@ -576,6 +576,13 @@
layerStackChange->set_layer_stack(layerStack);
}
+void SurfaceInterceptor::addDisplayFlagsLocked(Transaction* transaction, int32_t sequenceId,
+ uint32_t flags) {
+ DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
+ DisplayFlagsChange* flagsChange(dispChange->mutable_flags());
+ flagsChange->set_flags(flags);
+}
+
void SurfaceInterceptor::addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId,
uint32_t w, uint32_t h)
{
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 673f9e7..9a3ce2c 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -133,10 +133,10 @@
void addInitialDisplayStateLocked(Increment* increment, const DisplayDeviceState& display);
status_t writeProtoFileLocked();
- const sp<const Layer> getLayer(const wp<const IBinder>& weakHandle) const;
+ const sp<const Layer> getLayer(const wp<IBinder>& weakHandle) const;
int32_t getLayerId(const sp<const Layer>& layer) const;
int32_t getLayerIdFromWeakRef(const wp<const Layer>& layer) const;
- int32_t getLayerIdFromHandle(const sp<const IBinder>& weakHandle) const;
+ int32_t getLayerIdFromHandle(const sp<IBinder>& weakHandle) const;
Increment* createTraceIncrementLocked();
void addSurfaceCreationLocked(Increment* increment, const sp<const Layer>& layer);
@@ -185,6 +185,7 @@
const sp<const IGraphicBufferProducer>& surface);
void addDisplayLayerStackLocked(Transaction* transaction, int32_t sequenceId,
uint32_t layerStack);
+ void addDisplayFlagsLocked(Transaction* transaction, int32_t sequenceId, uint32_t flags);
void addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w,
uint32_t h);
void addDisplayProjectionLocked(Transaction* transaction, int32_t sequenceId,
diff --git a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
index 05858bf..fb4458a 100644
--- a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
+++ b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
@@ -20,6 +20,10 @@
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
+#include <chrono>
+
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
static constexpr int kRefreshRateOverlayCode = 1034;
static constexpr int kRefreshRateOverlayEnable = 1;
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 6912fcf..ab2064e 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -515,7 +515,8 @@
}
TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
- sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
+ sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
+ ISurfaceComposerClient::eFXSurfaceBufferState);
ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
@@ -532,6 +533,21 @@
ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
}
+TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
+ sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
+ ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
+
+ Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);
+
+ LayerCaptureArgs captureArgs;
+ captureArgs.layerHandle = redLayer->getHandle();
+ captureArgs.frameScaleX = INT32_MAX / 60;
+ captureArgs.frameScaleY = INT32_MAX / 60;
+
+ ScreenCaptureResults captureResults;
+ ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
+}
+
TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
ISurfaceComposerClient::eFXSurfaceBufferState);
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 162711d..a9e935d 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -279,7 +279,7 @@
}
bool waitForHotplugEvent(Display displayId, bool connected) {
- return waitForHotplugEvent(PhysicalDisplayId(displayId), connected);
+ return waitForHotplugEvent(physicalIdFromHwcDisplayId(displayId), connected);
}
bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) {
@@ -305,7 +305,7 @@
}
bool waitForModeChangedEvent(Display display, int32_t modeId) {
- PhysicalDisplayId displayId(display);
+ PhysicalDisplayId displayId = physicalIdFromHwcDisplayId(display);
int waitCount = 20;
while (waitCount--) {
while (!mReceivedDisplayEvents.empty()) {
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index b5086fa..8bd6e62 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -23,7 +23,10 @@
cc_test {
name: "libsurfaceflinger_unittest",
- defaults: ["surfaceflinger_defaults"],
+ defaults: [
+ "skia_renderengine_deps",
+ "surfaceflinger_defaults",
+ ],
test_suites: ["device-tests"],
sanitize: {
// Using the address sanitizer not only helps uncover issues in the code
@@ -51,6 +54,7 @@
"DisplayIdGeneratorTest.cpp",
"DisplayTransactionTest.cpp",
"DisplayDevice_GetBestColorModeTest.cpp",
+ "DisplayDevice_InitiateModeChange.cpp",
"DisplayDevice_SetProjectionTest.cpp",
"EventThreadTest.cpp",
"FpsReporterTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 560f139..98c1889 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -77,7 +77,7 @@
constexpr hal::HWLayerId HWC_LAYER = 5000;
constexpr Transform DEFAULT_TRANSFORM = static_cast<Transform>(0);
-constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID(42);
+constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;
@@ -108,6 +108,8 @@
mComposer = new Hwc2::mock::Composer();
mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
+
+ mFlinger.mutableMaxRenderTargetSize() = 16384;
}
~CompositionTest() {
@@ -519,8 +521,6 @@
static void setupLatchedBuffer(CompositionTest* test, sp<BufferQueueLayer> layer) {
// TODO: Eliminate the complexity of actually creating a buffer
- EXPECT_CALL(*test->mRenderEngine, getMaxTextureSize()).WillOnce(Return(16384));
- EXPECT_CALL(*test->mRenderEngine, getMaxViewportDims()).WillOnce(Return(16384));
status_t err =
layer->setDefaultBufferProperties(LayerProperties::WIDTH, LayerProperties::HEIGHT,
LayerProperties::FORMAT);
diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp
new file mode 100644
index 0000000..d4cfbbb
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "LibSurfaceFlingerUnittests"
+
+#include "DisplayTransactionTestHelpers.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace {
+
+using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
+
+class InitiateModeChangeTest : public DisplayTransactionTest {
+public:
+ using Event = scheduler::RefreshRateConfigEvent;
+
+ void SetUp() override {
+ injectFakeBufferQueueFactory();
+ injectFakeNativeWindowSurfaceFactory();
+
+ PrimaryDisplayVariant::setupHwcHotplugCallExpectations(this);
+ PrimaryDisplayVariant::setupFramebufferConsumerBufferQueueCallExpectations(this);
+ PrimaryDisplayVariant::setupFramebufferProducerBufferQueueCallExpectations(this);
+ PrimaryDisplayVariant::setupNativeWindowSurfaceCreationCallExpectations(this);
+ PrimaryDisplayVariant::setupHwcGetActiveConfigCallExpectations(this);
+
+ mFlinger.onComposerHalHotplug(PrimaryDisplayVariant::HWC_DISPLAY_ID, Connection::CONNECTED);
+
+ mDisplay = PrimaryDisplayVariant::makeFakeExistingDisplayInjector(this)
+ .setSupportedModes({kDisplayMode60, kDisplayMode90, kDisplayMode120})
+ .setActiveMode(kDisplayModeId60)
+ .inject();
+ }
+
+protected:
+ sp<DisplayDevice> mDisplay;
+
+ const DisplayModeId kDisplayModeId60 = DisplayModeId(0);
+ const DisplayModePtr kDisplayMode60 =
+ DisplayMode::Builder(hal::HWConfigId(kDisplayModeId60.value()))
+ .setId(kDisplayModeId60)
+ .setPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get())
+ .setVsyncPeriod(int32_t(16'666'667))
+ .setGroup(0)
+ .setHeight(1000)
+ .setWidth(1000)
+ .build();
+
+ const DisplayModeId kDisplayModeId90 = DisplayModeId(1);
+ const DisplayModePtr kDisplayMode90 =
+ DisplayMode::Builder(hal::HWConfigId(kDisplayModeId90.value()))
+ .setId(kDisplayModeId90)
+ .setPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get())
+ .setVsyncPeriod(int32_t(11'111'111))
+ .setGroup(0)
+ .setHeight(1000)
+ .setWidth(1000)
+ .build();
+
+ const DisplayModeId kDisplayModeId120 = DisplayModeId(2);
+ const DisplayModePtr kDisplayMode120 =
+ DisplayMode::Builder(hal::HWConfigId(kDisplayModeId120.value()))
+ .setId(kDisplayModeId120)
+ .setPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get())
+ .setVsyncPeriod(int32_t(8'333'333))
+ .setGroup(0)
+ .setHeight(1000)
+ .setWidth(1000)
+ .build();
+};
+
+TEST_F(InitiateModeChangeTest, setDesiredActiveMode_setCurrentMode) {
+ EXPECT_FALSE(mDisplay->setDesiredActiveMode({kDisplayMode60, Event::None}));
+ EXPECT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
+}
+
+TEST_F(InitiateModeChangeTest, setDesiredActiveMode_setNewMode) {
+ EXPECT_TRUE(mDisplay->setDesiredActiveMode({kDisplayMode90, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+ EXPECT_EQ(kDisplayMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
+
+ // Setting another mode should be cached but return false
+ EXPECT_FALSE(mDisplay->setDesiredActiveMode({kDisplayMode120, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+ EXPECT_EQ(kDisplayMode120, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
+}
+
+TEST_F(InitiateModeChangeTest, clearDesiredActiveModeState) {
+ EXPECT_TRUE(mDisplay->setDesiredActiveMode({kDisplayMode90, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+
+ mDisplay->clearDesiredActiveModeState();
+ ASSERT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
+}
+
+TEST_F(InitiateModeChangeTest, initiateModeChange) NO_THREAD_SAFETY_ANALYSIS {
+ EXPECT_TRUE(mDisplay->setDesiredActiveMode({kDisplayMode90, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+ EXPECT_EQ(kDisplayMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
+
+ hal::VsyncPeriodChangeConstraints constraints{
+ .desiredTimeNanos = systemTime(),
+ .seamlessRequired = false,
+ };
+ hal::VsyncPeriodChangeTimeline timeline;
+ EXPECT_EQ(OK,
+ mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
+ &timeline));
+ EXPECT_EQ(kDisplayMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
+
+ mDisplay->clearDesiredActiveModeState();
+ ASSERT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
+}
+
+TEST_F(InitiateModeChangeTest, getUpcomingActiveMode_desiredActiveModeChanged)
+NO_THREAD_SAFETY_ANALYSIS {
+ EXPECT_TRUE(mDisplay->setDesiredActiveMode({kDisplayMode90, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+ EXPECT_EQ(kDisplayMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
+
+ hal::VsyncPeriodChangeConstraints constraints{
+ .desiredTimeNanos = systemTime(),
+ .seamlessRequired = false,
+ };
+ hal::VsyncPeriodChangeTimeline timeline;
+ EXPECT_EQ(OK,
+ mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
+ &timeline));
+ EXPECT_EQ(kDisplayMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
+
+ EXPECT_FALSE(mDisplay->setDesiredActiveMode({kDisplayMode120, Event::None}));
+ ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
+ EXPECT_EQ(kDisplayMode120, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
+
+ EXPECT_EQ(kDisplayMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
+
+ EXPECT_EQ(OK,
+ mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
+ &timeline));
+ EXPECT_EQ(kDisplayMode120, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
+
+ mDisplay->clearDesiredActiveModeState();
+ ASSERT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
+}
+
+} // namespace
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
index dc04b6d..cd4a5c9 100644
--- a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
@@ -25,6 +25,7 @@
#include <gtest/gtest.h>
#include "DisplayHardware/DisplayIdentification.h"
+#include "DisplayHardware/Hash.h"
using ::testing::ElementsAre;
@@ -134,7 +135,7 @@
}
uint32_t hash(const char* str) {
- return static_cast<uint32_t>(std::hash<std::string_view>()(str));
+ return static_cast<uint32_t>(cityHash64Len0To16(str));
}
} // namespace
@@ -309,9 +310,9 @@
ASSERT_TRUE(tertiaryInfo);
// Display IDs should be unique.
- EXPECT_NE(primaryInfo->id, secondaryInfo->id);
- EXPECT_NE(primaryInfo->id, tertiaryInfo->id);
- EXPECT_NE(secondaryInfo->id, tertiaryInfo->id);
+ EXPECT_EQ(4633257497453176576, primaryInfo->id.value);
+ EXPECT_EQ(4621520285560261121, secondaryInfo->id.value);
+ EXPECT_EQ(4633127902230889474, tertiaryInfo->id.value);
}
TEST(DisplayIdentificationTest, deviceProductInfo) {
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index cc24323..60b0f53 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -122,7 +122,7 @@
sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
std::function<void(FakeDisplayDeviceInjector&)> injectExtra) {
- constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID(777);
+ constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(255u);
constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index b4a1481..28d0222 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -41,10 +41,13 @@
namespace {
-constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID(111);
-constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID(222);
-constexpr PhysicalDisplayId DISPLAY_ID_64BIT(0xabcd12349876fedcULL);
+constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(111u);
+constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(222u);
+constexpr PhysicalDisplayId DISPLAY_ID_64BIT =
+ PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu);
+
constexpr std::chrono::duration VSYNC_PERIOD(16ms);
+
class MockVSyncSource : public VSyncSource {
public:
const char* getName() const override { return "test"; }
@@ -543,17 +546,34 @@
}
TEST_F(EventThreadTest, postConfigChangedPrimary) {
- mThread->onModeChanged(INTERNAL_DISPLAY_ID, DisplayModeId(7), 16666666);
+ const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
+ .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
+ .setId(DisplayModeId(7))
+ .setVsyncPeriod(16666666)
+ .build();
+
+ mThread->onModeChanged(mode);
expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 7, 16666666);
}
TEST_F(EventThreadTest, postConfigChangedExternal) {
- mThread->onModeChanged(EXTERNAL_DISPLAY_ID, DisplayModeId(5), 16666666);
+ const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
+ .setPhysicalDisplayId(EXTERNAL_DISPLAY_ID)
+ .setId(DisplayModeId(5))
+ .setVsyncPeriod(16666666)
+ .build();
+
+ mThread->onModeChanged(mode);
expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5, 16666666);
}
TEST_F(EventThreadTest, postConfigChangedPrimary64bit) {
- mThread->onModeChanged(DISPLAY_ID_64BIT, DisplayModeId(7), 16666666);
+ const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
+ .setPhysicalDisplayId(DISPLAY_ID_64BIT)
+ .setId(DisplayModeId(7))
+ .setVsyncPeriod(16666666)
+ .build();
+ mThread->onModeChanged(mode);
expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7, 16666666);
}
@@ -562,7 +582,13 @@
sp<MockEventThreadConnection> suppressConnection =
createConnection(suppressConnectionEventRecorder);
- mThread->onModeChanged(INTERNAL_DISPLAY_ID, DisplayModeId(9), 16666666);
+ const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
+ .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
+ .setId(DisplayModeId(9))
+ .setVsyncPeriod(16666666)
+ .build();
+
+ mThread->onModeChanged(mode);
expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9, 16666666);
auto args = suppressConnectionEventRecorder.waitForCall();
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index b67ebca..bb21ad6 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -35,6 +35,7 @@
using testing::_;
using testing::Return;
+using testing::ReturnRef;
namespace android {
@@ -62,6 +63,10 @@
LayerHistory& history() { return *mScheduler->mutableLayerHistory(); }
const LayerHistory& history() const { return *mScheduler->mutableLayerHistory(); }
+ LayerHistory::Summary summarizeLayerHistory(nsecs_t now) {
+ return history().summarize(*mScheduler->refreshRateConfigs(), now);
+ }
+
size_t layerCount() const { return mScheduler->layerHistorySize(); }
size_t activeLayerCount() const NO_THREAD_SAFETY_ANALYSIS { return history().mActiveLayersEnd; }
@@ -101,7 +106,7 @@
history().record(layer.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += frameRate.getPeriodNsecs();
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(1, summary.size());
@@ -110,21 +115,26 @@
<< "Frame rate is " << frameRate;
}
- RefreshRateConfigs mConfigs{{DisplayMode::Builder(0)
- .setId(DisplayModeId(0))
- .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
- .setGroup(0)
- .build(),
- DisplayMode::Builder(1)
- .setId(DisplayModeId(1))
- .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
- .setGroup(0)
- .build()},
- DisplayModeId(0)};
+ std::shared_ptr<RefreshRateConfigs> mConfigs = std::make_shared<
+ RefreshRateConfigs>(DisplayModes{DisplayMode::Builder(0)
+ .setId(DisplayModeId(0))
+ .setPhysicalDisplayId(
+ PhysicalDisplayId::fromPort(0))
+ .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
+ .setGroup(0)
+ .build(),
+ DisplayMode::Builder(1)
+ .setId(DisplayModeId(1))
+ .setPhysicalDisplayId(
+ PhysicalDisplayId::fromPort(0))
+ .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
+ .setGroup(0)
+ .build()},
+ DisplayModeId(0));
- mock::NoOpSchedulerCallback mSchedulerCallback;
+ mock::SchedulerCallback mSchedulerCallback;
- TestableScheduler* const mScheduler = new TestableScheduler(mConfigs, mSchedulerCallback);
+ TestableScheduler* mScheduler = new TestableScheduler(mConfigs, mSchedulerCallback);
TestableSurfaceFlinger mFlinger;
};
@@ -142,22 +152,22 @@
const nsecs_t time = systemTime();
// No layers returned if no layers are active.
- EXPECT_TRUE(history().summarize(time).empty());
+ EXPECT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(0, activeLayerCount());
// Max returned if active layers have insufficient history.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
history().record(layer.get(), 0, time, LayerHistory::LayerUpdateType::Buffer);
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
}
// Max is returned since we have enough history but there is no timestamp votes.
for (int i = 0; i < 10; i++) {
history().record(layer.get(), 0, time, LayerHistory::LayerUpdateType::Buffer);
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
}
}
@@ -173,17 +183,17 @@
nsecs_t time = systemTime();
history().record(layer.get(), 0, time, LayerHistory::LayerUpdateType::Buffer);
- auto summary = history().summarize(time);
- ASSERT_EQ(1, history().summarize(time).size());
+ auto summary = summarizeLayerHistory(time);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
// Layer is still considered inactive so we expect to get Min
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
history().record(layer.get(), 0, time, LayerHistory::LayerUpdateType::Buffer);
- summary = history().summarize(time);
- EXPECT_TRUE(history().summarize(time).empty());
+ summary = summarizeLayerHistory(time);
+ EXPECT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(0, activeLayerCount());
}
@@ -201,9 +211,9 @@
time += LO_FPS_PERIOD;
}
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, history().summarize(time)[0].vote);
- EXPECT_TRUE(LO_FPS.equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(LO_FPS.equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
}
@@ -224,13 +234,13 @@
time += HI_FPS_PERIOD;
}
- ASSERT_TRUE(history().summarize(time).empty());
+ ASSERT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(history().summarize(time).empty());
+ ASSERT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(0, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -251,14 +261,14 @@
time += HI_FPS_PERIOD;
}
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Min, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(history().summarize(time).empty());
+ ASSERT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(0, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -279,14 +289,14 @@
time += LO_FPS_PERIOD;
}
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(history().summarize(time).empty());
+ ASSERT_TRUE(summarizeLayerHistory(time).empty());
EXPECT_EQ(0, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -307,18 +317,18 @@
time += HI_FPS_PERIOD;
}
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, history().summarize(time)[0].vote);
- EXPECT_TRUE(Fps(73.4f).equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(Fps(73.4f).equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive, but the vote stays
setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, history().summarize(time)[0].vote);
- EXPECT_TRUE(Fps(73.4f).equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(Fps(73.4f).equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -339,20 +349,20 @@
time += HI_FPS_PERIOD;
}
- ASSERT_EQ(1, history().summarize(time).size());
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
- history().summarize(time)[0].vote);
- EXPECT_TRUE(Fps(73.4f).equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(Fps(73.4f).equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
// layer became inactive, but the vote stays
setDefaultLayerVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_EQ(1, history().summarize(time).size());
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
- history().summarize(time)[0].vote);
- EXPECT_TRUE(Fps(73.4f).equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(Fps(73.4f).equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -383,7 +393,7 @@
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
history().record(layer1.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(1, summary.size());
@@ -395,7 +405,7 @@
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += HI_FPS_PERIOD;
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
// layer1 is still active but infrequent.
@@ -404,7 +414,7 @@
ASSERT_EQ(2, summary.size());
EXPECT_EQ(LayerHistory::LayerVoteType::Min, summary[0].vote);
ASSERT_EQ(LayerHistory::LayerVoteType::Heuristic, summary[1].vote);
- EXPECT_TRUE(HI_FPS.equalsWithMargin(history().summarize(time)[1].desiredRefreshRate));
+ EXPECT_TRUE(HI_FPS.equalsWithMargin(summarizeLayerHistory(time)[1].desiredRefreshRate));
EXPECT_EQ(2, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
@@ -414,7 +424,7 @@
for (int i = 0; i < 2 * PRESENT_TIME_HISTORY_SIZE; i++) {
history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += LO_FPS_PERIOD;
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(1, summary.size());
@@ -433,7 +443,7 @@
history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += HI_FPS_PERIOD;
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(2, summary.size());
@@ -445,7 +455,7 @@
// layer3 becomes recently active.
history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
ASSERT_EQ(2, summary.size());
EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, summary[0].vote);
EXPECT_TRUE(LO_FPS.equalsWithMargin(summary[0].desiredRefreshRate));
@@ -456,7 +466,7 @@
// layer1 expires.
layer1.clear();
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
ASSERT_EQ(2, summary.size());
EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, summary[0].vote);
EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, summary[0].vote);
@@ -472,7 +482,7 @@
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += LO_FPS_PERIOD;
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(1, summary.size());
@@ -483,7 +493,7 @@
// layer2 expires.
layer2.clear();
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
EXPECT_TRUE(summary.empty());
EXPECT_EQ(1, layerCount());
EXPECT_EQ(0, activeLayerCount());
@@ -493,7 +503,7 @@
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE + FREQUENT_LAYER_WINDOW_SIZE + 1; i++) {
history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += HI_FPS_PERIOD;
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
}
ASSERT_EQ(1, summary.size());
@@ -505,7 +515,7 @@
// layer3 expires.
layer3.clear();
- summary = history().summarize(time);
+ summary = summarizeLayerHistory(time);
EXPECT_TRUE(summary.empty());
EXPECT_EQ(0, layerCount());
EXPECT_EQ(0, activeLayerCount());
@@ -526,8 +536,8 @@
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
EXPECT_EQ(1, layerCount());
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
}
@@ -537,8 +547,8 @@
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
EXPECT_EQ(1, layerCount());
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Min, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
@@ -551,8 +561,8 @@
time += HI_FPS_PERIOD;
EXPECT_EQ(1, layerCount());
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Min, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -562,8 +572,8 @@
time += HI_FPS_PERIOD;
EXPECT_EQ(1, layerCount());
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
}
@@ -590,10 +600,10 @@
LayerHistory::LayerUpdateType::Buffer);
EXPECT_EQ(2, layerCount());
- ASSERT_EQ(1, history().summarize(time).size());
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
- history().summarize(time)[0].vote);
- EXPECT_TRUE(Fps(60.0f).equalsWithMargin(history().summarize(time)[0].desiredRefreshRate));
+ summarizeLayerHistory(time)[0].vote);
+ EXPECT_TRUE(Fps(60.0f).equalsWithMargin(summarizeLayerHistory(time)[0].desiredRefreshRate));
EXPECT_EQ(2, activeLayerCount());
EXPECT_EQ(2, frequentLayerCount(time));
}
@@ -617,8 +627,8 @@
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
}
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Min, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
EXPECT_EQ(0, animatingLayerCount(time));
@@ -627,8 +637,8 @@
history().record(layer.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Min, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
EXPECT_EQ(0, animatingLayerCount(time));
@@ -637,8 +647,8 @@
history().record(layer.get(), time, time, LayerHistory::LayerUpdateType::AnimationTX);
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
- ASSERT_EQ(1, history().summarize(time).size());
- EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(time)[0].vote);
+ ASSERT_EQ(1, summarizeLayerHistory(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::Max, summarizeLayerHistory(time)[0].vote);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
EXPECT_EQ(1, animatingLayerCount(time));
@@ -727,13 +737,13 @@
}
if (time - startTime > PRESENT_TIME_HISTORY_DURATION.count()) {
- ASSERT_NE(0, history().summarize(time).size());
- ASSERT_GE(2, history().summarize(time).size());
+ ASSERT_NE(0, summarizeLayerHistory(time).size());
+ ASSERT_GE(2, summarizeLayerHistory(time).size());
bool max = false;
bool min = false;
Fps heuristic{0.0};
- for (const auto& layer : history().summarize(time)) {
+ for (const auto& layer : summarizeLayerHistory(time)) {
if (layer.vote == LayerHistory::LayerVoteType::Heuristic) {
heuristic = layer.desiredRefreshRate;
} else if (layer.vote == LayerHistory::LayerVoteType::Max) {
@@ -746,7 +756,7 @@
if (infrequentLayerUpdates > FREQUENT_LAYER_WINDOW_SIZE) {
EXPECT_TRUE(Fps(24.0f).equalsWithMargin(heuristic));
EXPECT_FALSE(max);
- if (history().summarize(time).size() == 2) {
+ if (summarizeLayerHistory(time).size() == 2) {
EXPECT_TRUE(min);
}
}
diff --git a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
index 6916764..597e5e7 100644
--- a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
@@ -72,7 +72,8 @@
mIdleTimer->stop();
}
-TEST_F(OneShotTimerTest, resetTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_resetTest) {
fake::FakeClock* clock = new fake::FakeClock();
mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
mResetTimerCallback.getInvocable(),
@@ -94,7 +95,8 @@
EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
}
-TEST_F(OneShotTimerTest, resetBackToBackTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_resetBackToBackTest) {
fake::FakeClock* clock = new fake::FakeClock();
mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
mResetTimerCallback.getInvocable(),
@@ -144,7 +146,8 @@
EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
}
-TEST_F(OneShotTimerTest, idleTimerIdlesTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_idleTimerIdlesTest) {
fake::FakeClock* clock = new fake::FakeClock();
mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
mResetTimerCallback.getInvocable(),
@@ -169,7 +172,8 @@
EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
}
-TEST_F(OneShotTimerTest, timeoutCallbackExecutionTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_timeoutCallbackExecutionTest) {
fake::FakeClock* clock = new fake::FakeClock();
mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
mResetTimerCallback.getInvocable(),
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 3423bd5..c04919f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -51,8 +51,7 @@
~RefreshRateConfigsTest();
RefreshRate createRefreshRate(DisplayModePtr displayMode) {
- return {displayMode->getId(), displayMode, displayMode->getFps(),
- RefreshRate::ConstructorTag(0)};
+ return {displayMode, RefreshRate::ConstructorTag(0)};
}
Fps findClosestKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs, Fps frameRate) {
@@ -147,24 +146,17 @@
DisplayModes m60_120Device = {mConfig60, mConfig120};
// Expected RefreshRate objects
- RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, Fps(60),
- RefreshRate::ConstructorTag(0)};
- RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60,
- createDisplayMode(HWC_CONFIG_ID_60, 0, 16666665),
- Fps(60), RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, Fps(90),
- RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup,
- Fps(90), RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90,
- mConfig90DifferentResolution, Fps(90),
+ RefreshRate mExpected60Config = {mConfig60, RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpectedAlmost60Config = {createDisplayMode(HWC_CONFIG_ID_60, 0, 16666665),
+ RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected90Config = {mConfig90, RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected90DifferentGroupConfig = {mConfig90DifferentGroup,
+ RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected90DifferentResolutionConfig = {mConfig90DifferentResolution,
RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, Fps(72.0f),
- RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, Fps(30),
- RefreshRate::ConstructorTag(0)};
- RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120),
- RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected72Config = {mConfig72, RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected30Config = {mConfig30, RefreshRate::ConstructorTag(0)};
+ RefreshRate mExpected120Config = {mConfig120, RefreshRate::ConstructorTag(0)};
private:
DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod,
@@ -189,6 +181,7 @@
int64_t vsyncPeriod, ui::Size resolution) {
return DisplayMode::Builder(hal::HWConfigId(modeId.value()))
.setId(modeId)
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(int32_t(vsyncPeriod))
.setGroup(group)
.setHeight(resolution.height)
@@ -2272,26 +2265,6 @@
ASSERT_TRUE(frameRateOverrides.empty());
}
-TEST_F(RefreshRateConfigsTest, updateDisplayModes) {
- auto refreshRateConfigs =
- std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
- /*currentConfigId=*/HWC_CONFIG_ID_30);
- refreshRateConfigs->setDisplayManagerPolicy({DisplayModeId(HWC_CONFIG_ID_30),
- /* allowGroupSwitching */ false,
- /* range */ {Fps(30.0f), Fps(30.0f)}});
-
- refreshRateConfigs->updateDisplayModes(m60_90Device, HWC_CONFIG_ID_60);
-
- const auto currentRefreshRate = refreshRateConfigs->getCurrentRefreshRate();
- EXPECT_TRUE(currentRefreshRate.getFps().equalsWithMargin(Fps(60.0)));
- EXPECT_EQ(currentRefreshRate.getModeId(), HWC_CONFIG_ID_60);
-
- EXPECT_TRUE(
- getMaxSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(90.0)));
- EXPECT_TRUE(
- getMinSupportedRefreshRate(*refreshRateConfigs).getFps().equalsWithMargin(Fps(60.0)));
-}
-
} // namespace
} // namespace scheduler
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index bf07106..0a8759d 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -81,6 +81,7 @@
int64_t vsyncPeriod) {
return DisplayMode::Builder(static_cast<hal::HWConfigId>(modeId.value()))
.setId(modeId)
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(static_cast<int32_t>(vsyncPeriod))
.setGroup(group)
.build();
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index f680d80..e2b3993 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -34,7 +34,7 @@
namespace android {
namespace {
-constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID(999);
+constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = PhysicalDisplayId::fromPort(255u);
class SchedulerTest : public testing::Test {
protected:
@@ -53,16 +53,19 @@
const DisplayModePtr mode60 = DisplayMode::Builder(0)
.setId(DisplayModeId(0))
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(Fps(60.f).getPeriodNsecs())
.setGroup(0)
.build();
const DisplayModePtr mode120 = DisplayMode::Builder(1)
.setId(DisplayModeId(1))
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(Fps(120.f).getPeriodNsecs())
.setGroup(0)
.build();
- scheduler::RefreshRateConfigs mConfigs{{mode60}, mode60->getId()};
+ std::shared_ptr<scheduler::RefreshRateConfigs> mConfigs =
+ std::make_shared<scheduler::RefreshRateConfigs>(DisplayModes{mode60}, mode60->getId());
mock::SchedulerCallback mSchedulerCallback;
@@ -171,7 +174,7 @@
mScheduler->setDisplayPowerState(kPowerStateNormal);
constexpr uint32_t kDisplayArea = 999'999;
- mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea);
+ mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
EXPECT_CALL(mSchedulerCallback, changeRefreshRate(_, _)).Times(0);
mScheduler->chooseRefreshRateForContent();
@@ -182,7 +185,9 @@
sp<mock::MockLayer> layer = sp<mock::MockLayer>::make(mFlinger.flinger());
ASSERT_EQ(static_cast<size_t>(1), mScheduler->layerHistorySize());
- mConfigs.updateDisplayModes({mode60, mode120}, /* activeMode */ mode60->getId());
+ mScheduler->setRefreshRateConfigs(
+ std::make_shared<scheduler::RefreshRateConfigs>(DisplayModes{mode60, mode120},
+ mode60->getId()));
ASSERT_EQ(static_cast<size_t>(0), mScheduler->getNumActiveLayers());
mScheduler->recordLayerHistory(layer.get(), 0, LayerHistory::LayerUpdateType::Buffer);
@@ -194,20 +199,21 @@
// onModeChange is called.
mScheduler->clearOptionalFieldsInFeatures();
EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
- EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0);
+ EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
}
TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
- DisplayModeId modeId = DisplayModeId(111);
- nsecs_t vsyncPeriod = 111111;
+ const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
+ .setId(DisplayModeId(111))
+ .setPhysicalDisplayId(PHYSICAL_DISPLAY_ID)
+ .setVsyncPeriod(111111)
+ .build();
// If the handle is incorrect, the function should return before
// onModeChange is called.
Scheduler::ConnectionHandle invalidHandle = {.id = 123};
- EXPECT_NO_FATAL_FAILURE(mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
- PHYSICAL_DISPLAY_ID, modeId,
- vsyncPeriod));
- EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0);
+ EXPECT_NO_FATAL_FAILURE(mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle, mode));
+ EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
}
TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
@@ -225,7 +231,9 @@
}
TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
- mConfigs.updateDisplayModes({mode60, mode120}, /* activeMode */ mode60->getId());
+ mScheduler->setRefreshRateConfigs(
+ std::make_shared<scheduler::RefreshRateConfigs>(DisplayModes{mode60, mode120},
+ mode60->getId()));
sp<mock::MockLayer> layer = sp<mock::MockLayer>::make(mFlinger.flinger());
@@ -235,7 +243,7 @@
mScheduler->setDisplayPowerState(kPowerStateNormal);
constexpr uint32_t kDisplayArea = 999'999;
- mScheduler->onPrimaryDisplayAreaChanged(kDisplayArea);
+ mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
EXPECT_CALL(mSchedulerCallback, changeRefreshRate(Is120Hz(), _)).Times(1);
mScheduler->chooseRefreshRateForContent();
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 1ed52ea..8e7554b 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -479,7 +479,9 @@
->record(child.get(), 0, 0, LayerHistory::LayerUpdateType::Buffer);
const auto layerHistorySummary =
- mFlinger.mutableScheduler().mutableLayerHistory()->summarize(0);
+ mFlinger.mutableScheduler()
+ .mutableLayerHistory()
+ ->summarize(*mFlinger.mutableScheduler().refreshRateConfigs(), 0);
ASSERT_EQ(2u, layerHistorySummary.size());
EXPECT_TRUE(FRAME_RATE_VOTE1.rate.equalsWithMargin(layerHistorySummary[0].desiredRefreshRate));
EXPECT_TRUE(FRAME_RATE_VOTE1.rate.equalsWithMargin(layerHistorySummary[1].desiredRefreshRate));
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp
index be01984..fc40818 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp
@@ -224,6 +224,74 @@
EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
}
+TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfFlagsNotChanged) {
+ using Case = SimplePrimaryDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // A display is set up
+ auto display = Case::Display::makeFakeExistingDisplayInjector(this);
+ display.inject();
+
+ // The display has flags set
+ display.mutableCurrentDisplayState().flags = 1u;
+
+ // The incoming request sets a different layer stack
+ DisplayState state;
+ state.what = DisplayState::eFlagsChanged;
+ state.token = display.token();
+ state.flags = 1u;
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ uint32_t flags = mFlinger.setDisplayStateLocked(state);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // The returned flags are empty
+ EXPECT_EQ(0u, flags);
+
+ // The desired display state has been set to the new value.
+ EXPECT_EQ(1u, display.getCurrentDisplayState().flags);
+}
+
+TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfFlagsChanged) {
+ using Case = SimplePrimaryDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // A display is set up
+ auto display = Case::Display::makeFakeExistingDisplayInjector(this);
+ display.inject();
+
+ // The display has a layer stack set
+ display.mutableCurrentDisplayState().flags = 0u;
+
+ // The incoming request sets a different layer stack
+ DisplayState state;
+ state.what = DisplayState::eFlagsChanged;
+ state.token = display.token();
+ state.flags = 1u;
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ uint32_t flags = mFlinger.setDisplayStateLocked(state);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // The returned flags indicate a transaction is needed
+ EXPECT_EQ(eDisplayTransactionNeeded, flags);
+
+ // The desired display state has been set to the new value.
+ EXPECT_EQ(1u, display.getCurrentDisplayState().flags);
+}
+
TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
using Case = SimplePrimaryDisplayCase;
constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 41fd6e3..a99dabe 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -32,15 +32,18 @@
class TestableScheduler : public Scheduler {
public:
- TestableScheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback)
+ TestableScheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
+ ISchedulerCallback& callback)
: TestableScheduler(std::make_unique<mock::VsyncController>(),
- std::make_unique<mock::VSyncTracker>(), configs, callback) {}
+ std::make_unique<mock::VSyncTracker>(), refreshRateConfigs,
+ callback) {}
TestableScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,
std::unique_ptr<scheduler::VSyncTracker> vsyncTracker,
- const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback)
- : Scheduler({std::move(vsyncController), std::move(vsyncTracker), nullptr}, configs,
- callback, createLayerHistory(configs),
+ const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
+ ISchedulerCallback& callback)
+ : Scheduler({std::move(vsyncController), std::move(vsyncTracker), nullptr},
+ refreshRateConfigs, callback, createLayerHistory(),
{.supportKernelTimer = false, .useContentDetection = true}) {}
// Used to inject mock event thread.
@@ -64,6 +67,8 @@
return mutableLayerHistory()->mLayerInfos.size();
}
+ auto refreshRateConfigs() { return holdRefreshRateConfigs(); }
+
size_t getNumActiveLayers() NO_THREAD_SAFETY_ANALYSIS {
if (!mLayerHistory) return 0;
return mutableLayerHistory()->mActiveLayersEnd;
@@ -95,9 +100,8 @@
mFeatures.cachedModeChangedParams.reset();
}
- void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
- DisplayModeId modeId, nsecs_t vsyncPeriod) {
- return Scheduler::onNonPrimaryDisplayModeChanged(handle, displayId, modeId, vsyncPeriod);
+ void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
+ return Scheduler::onNonPrimaryDisplayModeChanged(handle, mode);
}
~TestableScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index cf67593..56ae414 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -82,8 +82,8 @@
return std::make_unique<scheduler::FakePhaseOffsets>();
}
- std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
- ISchedulerCallback&) override {
+ std::unique_ptr<Scheduler> createScheduler(
+ const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&) override {
return nullptr;
}
@@ -209,6 +209,7 @@
ISchedulerCallback* callback = nullptr, bool hasMultipleModes = false) {
DisplayModes modes{DisplayMode::Builder(0)
.setId(DisplayModeId(0))
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(16'666'667)
.setGroup(0)
.build()};
@@ -216,25 +217,24 @@
if (hasMultipleModes) {
modes.emplace_back(DisplayMode::Builder(1)
.setId(DisplayModeId(1))
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setVsyncPeriod(11'111'111)
.setGroup(0)
.build());
}
const auto currMode = DisplayModeId(0);
- mFlinger->mRefreshRateConfigs =
- std::make_unique<scheduler::RefreshRateConfigs>(modes, currMode);
- const auto currFps =
- mFlinger->mRefreshRateConfigs->getRefreshRateFromModeId(currMode).getFps();
- mFlinger->mRefreshRateStats =
- std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps,
- /*powerMode=*/hal::PowerMode::OFF);
+ mRefreshRateConfigs = std::make_shared<scheduler::RefreshRateConfigs>(modes, currMode);
+ const auto currFps = mRefreshRateConfigs->getCurrentRefreshRate().getFps();
mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(currFps);
mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make(
mFlinger->mVsyncConfiguration->getCurrentConfigs());
+ mFlinger->mRefreshRateStats =
+ std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps,
+ /*powerMode=*/hal::PowerMode::OFF);
mScheduler = new TestableScheduler(std::move(vsyncController), std::move(vsyncTracker),
- *mFlinger->mRefreshRateConfigs, *(callback ?: this));
+ mRefreshRateConfigs, *(callback ?: this));
mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread));
mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));
@@ -435,6 +435,7 @@
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutablePowerAdvisor() { return mFlinger->mPowerAdvisor; }
auto& mutableDebugDisableHWC() { return mFlinger->mDebugDisableHWC; }
+ auto& mutableMaxRenderTargetSize() { return mFlinger->mMaxRenderTargetSize; }
auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; }
auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
@@ -644,6 +645,7 @@
DisplayModePtr activeMode =
DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG)
.setId(mActiveModeId)
+ .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
.setWidth(FakeHwcDisplayInjector::DEFAULT_WIDTH)
.setHeight(FakeHwcDisplayInjector::DEFAULT_HEIGHT)
.setVsyncPeriod(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)
@@ -654,6 +656,7 @@
DisplayModes modes{activeMode};
mCreationArgs.supportedModes = modes;
+ mCreationArgs.refreshRateConfigs = flinger.mRefreshRateConfigs;
}
sp<IBinder> token() const { return mDisplayToken; }
@@ -723,7 +726,7 @@
return *this;
}
- sp<DisplayDevice> inject() {
+ sp<DisplayDevice> inject() NO_THREAD_SAFETY_ANALYSIS {
const auto displayId = mCreationArgs.compositionDisplay->getDisplayId();
DisplayDeviceState state;
@@ -770,6 +773,7 @@
surfaceflinger::test::Factory mFactory;
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
TestableScheduler* mScheduler = nullptr;
+ std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 7c431a0..1a50427 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -74,6 +74,7 @@
EXPECT_CALL(*mVSyncTracker, currentPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
+ mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
mFlinger.setupScheduler(std::unique_ptr<mock::VsyncController>(mVsyncController),
std::unique_ptr<mock::VSyncTracker>(mVSyncTracker),
std::move(eventThread), std::move(sfEventThread));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 7de1872..20d41e6 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -18,6 +18,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
+#undef LOG_TAG
#define LOG_TAG "MockComposer"
#include "mock/DisplayHardware/MockComposer.h"
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 485b4ac..d25973e 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -33,7 +33,7 @@
MOCK_METHOD0(onScreenReleased, void());
MOCK_METHOD0(onScreenAcquired, void());
MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool));
- MOCK_METHOD3(onModeChanged, void(PhysicalDisplayId, DisplayModeId, nsecs_t));
+ MOCK_METHOD1(onModeChanged, void(DisplayModePtr));
MOCK_METHOD2(onFrameRateOverridesChanged,
void(PhysicalDisplayId, std::vector<FrameRateOverride>));
MOCK_CONST_METHOD1(dump, void(std::string&));
diff --git a/services/surfaceflinger/tests/utils/CallbackUtils.h b/services/surfaceflinger/tests/utils/CallbackUtils.h
index 459b35c..f4a3425 100644
--- a/services/surfaceflinger/tests/utils/CallbackUtils.h
+++ b/services/surfaceflinger/tests/utils/CallbackUtils.h
@@ -20,8 +20,12 @@
#include <gui/SurfaceControl.h>
#include <ui/Fence.h>
#include <utils/Timers.h>
+#include <chrono>
#include <thread>
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
+
namespace android {
namespace {
diff --git a/vulkan/README.md b/vulkan/README.md
index 185aa39..144805c 100644
--- a/vulkan/README.md
+++ b/vulkan/README.md
@@ -14,7 +14,7 @@
## Code Generation
-We generate several parts of the loader and tools driectly from the Vulkan Registry (external/vulkan-headers/registry/vk.xml). Code generation must be done manually because the generator is not part of the platform toolchain (yet?). Files named `foo_gen.*` are generated by the code generator.
+We generate several parts of the loader and tools directly from the Vulkan Registry (external/vulkan-headers/registry/vk.xml). Code generation must be done manually because the generator is not part of the platform toolchain (yet?). Files named `foo_gen.*` are generated by the code generator.
### Run The Code Generator
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index 26052fb..33401d2 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -560,6 +560,7 @@
}
static const char* const known_non_device_names[] = {
+ "vkAcquireDrmDisplayEXT",
"vkCreateAndroidSurfaceKHR",
"vkCreateDebugReportCallbackEXT",
"vkCreateDebugUtilsMessengerEXT",
@@ -581,6 +582,7 @@
"vkEnumeratePhysicalDevices",
"vkGetDisplayModeProperties2KHR",
"vkGetDisplayPlaneCapabilities2KHR",
+ "vkGetDrmDisplayEXT",
"vkGetInstanceProcAddr",
"vkGetPhysicalDeviceCalibrateableTimeDomainsEXT",
"vkGetPhysicalDeviceDisplayPlaneProperties2KHR",
@@ -624,6 +626,8 @@
"vkGetPhysicalDeviceSurfacePresentModesKHR",
"vkGetPhysicalDeviceSurfaceSupportKHR",
"vkGetPhysicalDeviceToolPropertiesEXT",
+ "vkGetPhysicalDeviceVideoCapabilitiesKHR",
+ "vkGetPhysicalDeviceVideoFormatPropertiesKHR",
"vkSubmitDebugUtilsMessageEXT",
};
// clang-format on
diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py
index 72fd4fb..4176509 100644
--- a/vulkan/scripts/generator_common.py
+++ b/vulkan/scripts/generator_common.py
@@ -33,6 +33,7 @@
'VK_EXT_metal_surface',
'VK_FUCHSIA_imagepipe_surface',
'VK_GGP_stream_descriptor_surface',
+ 'VK_HUAWEI_subpass_shading',
'VK_KHR_display',
'VK_KHR_display_swapchain',
'VK_KHR_external_fence_win32',
@@ -47,11 +48,13 @@
'VK_MVK_ios_surface',
'VK_MVK_macos_surface',
'VK_NN_vi_surface',
+ 'VK_NV_acquire_winrt_display',
'VK_NV_cooperative_matrix',
'VK_NV_coverage_reduction_mode',
'VK_NV_external_memory_win32',
'VK_NV_win32_keyed_mutex',
'VK_NVX_image_view_handle',
+ 'VK_QNX_screen_surface',
]
# Extensions having functions exported by the loader.