From 2a0f54e336fb757b86a1f0f00c22786ece07c124 Mon Sep 17 00:00:00 2001 From: Dakkshesh Date: Mon, 4 Aug 2025 15:36:17 +0530 Subject: [PATCH] src: cpp: Pull required headers from AOSP tag: android-16.0.0_r1 Signed-off-by: Dakkshesh --- NOTICE | 16 + app/src/main/cpp/external/AOSP/LICENSE | 202 ++ .../AOSP/include/android-base/unique_fd.h | 322 ++++ .../cpp/external/AOSP/include/binder/Binder.h | 165 ++ .../external/AOSP/include/binder/BpBinder.h | 247 +++ .../cpp/external/AOSP/include/binder/Common.h | 54 + .../external/AOSP/include/binder/IBinder.h | 356 ++++ .../external/AOSP/include/binder/IInterface.h | 298 +++ .../AOSP/include/binder/IPCThreadState.h | 264 +++ .../AOSP/include/binder/IServiceManager.h | 354 ++++ .../cpp/external/AOSP/include/binder/Parcel.h | 1674 +++++++++++++++++ .../AOSP/include/binder/ProcessState.h | 202 ++ .../external/AOSP/include/binder/RpcThreads.h | 139 ++ .../external/AOSP/include/binder/unique_fd.h | 116 ++ .../cpp/external/AOSP/include/utils/Errors.h | 77 + .../AOSP/include/utils/LightRefBase.h | 76 + .../cpp/external/AOSP/include/utils/RefBase.h | 818 ++++++++ .../external/AOSP/include/utils/String16.h | 411 ++++ .../cpp/external/AOSP/include/utils/String8.h | 378 ++++ .../AOSP/include/utils/StrongPointer.h | 370 ++++ .../external/AOSP/include/utils/TypeHelpers.h | 341 ++++ .../cpp/external/AOSP/include/utils/Unicode.h | 139 ++ .../cpp/external/AOSP/include/utils/Vector.h | 418 ++++ .../external/AOSP/include/utils/VectorImpl.h | 182 ++ 24 files changed, 7619 insertions(+) create mode 100644 NOTICE create mode 100644 app/src/main/cpp/external/AOSP/LICENSE create mode 100644 app/src/main/cpp/external/AOSP/include/android-base/unique_fd.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/Binder.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/BpBinder.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/Common.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/IBinder.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/IInterface.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/IPCThreadState.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/IServiceManager.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/Parcel.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/ProcessState.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/RpcThreads.h create mode 100644 app/src/main/cpp/external/AOSP/include/binder/unique_fd.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/Errors.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/LightRefBase.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/RefBase.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/String16.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/String8.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/StrongPointer.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/TypeHelpers.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/Unicode.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/Vector.h create mode 100644 app/src/main/cpp/external/AOSP/include/utils/VectorImpl.h diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..ce998d3 --- /dev/null +++ b/NOTICE @@ -0,0 +1,16 @@ +This project is licensed under the GNU General Public License v3.0 +(see LICENSE file). + +Third-party components: +----------------------- + +1. Portions of this project include code from the Android Open Source Project (AOSP) located in: + app/src/main/cpp/external/AOSP/ + The corresponding Apache License 2.0 is provided in: + app/src/main/cpp/external/AOSP/LICENSE + +2. This project includes the LSPlt library as a Git submodule located in: + app/src/main/cpp/external/LSPlt/ + LSPlt is licensed under the GNU Lesser General Public License v3.0 (LGPLv3). + The license can be viewed at: + https://github.com/LSPosed/LSPlt/blob/master/LICENSE diff --git a/app/src/main/cpp/external/AOSP/LICENSE b/app/src/main/cpp/external/AOSP/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/app/src/main/cpp/external/AOSP/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/app/src/main/cpp/external/AOSP/include/android-base/unique_fd.h b/app/src/main/cpp/external/AOSP/include/android-base/unique_fd.h new file mode 100644 index 0000000..1ffe02f --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/android-base/unique_fd.h @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include + +// DO NOT INCLUDE OTHER LIBBASE HEADERS HERE! +// This file gets used in libbinder, and libbinder is used everywhere. +// Including other headers from libbase frequently results in inclusion of +// android-base/macros.h, which causes macro collisions. + +#if defined(__BIONIC__) +#include +#endif +#if !defined(_WIN32) && !defined(__TRUSTY__) +#include +#endif + +namespace android { +namespace base { + +// Container for a file descriptor that automatically closes the descriptor as +// it goes out of scope. +// +// unique_fd ufd(open("/some/path", "r")); +// if (ufd.get() == -1) return error; +// +// // Do something useful, possibly including 'return'. +// +// return 0; // Descriptor is closed for you. +// +// See also the Pipe()/Socketpair()/Fdopen()/Fdopendir() functions in this file +// that provide interoperability with the libc functions with the same (but +// lowercase) names. +// +// unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help +// you find this class if you're searching for one of those names. +// +// unique_fd itself is a specialization of unique_fd_impl with a default closer. +template +class unique_fd_impl final { + public: + unique_fd_impl() {} + + explicit unique_fd_impl(int fd) { reset(fd); } + ~unique_fd_impl() { reset(); } + + unique_fd_impl(const unique_fd_impl&) = delete; + void operator=(const unique_fd_impl&) = delete; + unique_fd_impl(unique_fd_impl&& other) noexcept { reset(other.release()); } + unique_fd_impl& operator=(unique_fd_impl&& s) noexcept { + int fd = s.fd_; + s.fd_ = -1; + reset(fd, &s); + return *this; + } + + [[clang::reinitializes]] void reset(int new_value = -1) { reset(new_value, nullptr); } + + int get() const { return fd_; } + +#if !defined(ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION) + // unique_fd's operator int is dangerous, but we have way too much code that + // depends on it, so make this opt-in at first. + operator int() const { return get(); } // NOLINT +#endif + + bool operator>=(int rhs) const { return get() >= rhs; } + bool operator<(int rhs) const { return get() < rhs; } + bool operator==(int rhs) const { return get() == rhs; } + bool operator!=(int rhs) const { return get() != rhs; } + bool operator==(const unique_fd_impl& rhs) const { return get() == rhs.get(); } + bool operator!=(const unique_fd_impl& rhs) const { return get() != rhs.get(); } + + // Catch bogus error checks (i.e.: "!fd" instead of "fd != -1"). + bool operator!() const = delete; + + bool ok() const { return get() >= 0; } + + int release() __attribute__((warn_unused_result)) { + tag(fd_, this, nullptr); + int ret = fd_; + fd_ = -1; + return ret; + } + + private: + void reset(int new_value, void* previous_tag) { + int previous_errno = errno; + + if (fd_ != -1) { + close(fd_, this); + } + + fd_ = new_value; + if (new_value != -1) { + tag(new_value, previous_tag, this); + } + + errno = previous_errno; + } + + int fd_ = -1; + + // Template magic to use Closer::Tag if available, and do nothing if not. + // If Closer::Tag exists, this implementation is preferred, because int is a better match. + // If not, this implementation is SFINAEd away, and the no-op below is the only one that exists. + template + static auto tag(int fd, void* old_tag, void* new_tag) + -> decltype(T::Tag(fd, old_tag, new_tag), void()) { + T::Tag(fd, old_tag, new_tag); + } + + template + static void tag(long, void*, void*) { + // No-op. + } + + // Same as above, to select between Closer::Close(int) and Closer::Close(int, void*). + template + static auto close(int fd, void* tag_value) -> decltype(T::Close(fd, tag_value), void()) { + T::Close(fd, tag_value); + } + + template + static auto close(int fd, void*) -> decltype(T::Close(fd), void()) { + T::Close(fd); + } +}; + +// The actual details of closing are factored out to support unusual cases. +// Almost everyone will want this DefaultCloser, which handles fdsan on bionic. +struct DefaultCloser { +#if defined(__BIONIC__) + static void Tag(int fd, void* old_addr, void* new_addr) { + if (android_fdsan_exchange_owner_tag) { + uint64_t old_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, + reinterpret_cast(old_addr)); + uint64_t new_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, + reinterpret_cast(new_addr)); + android_fdsan_exchange_owner_tag(fd, old_tag, new_tag); + } + } + static void Close(int fd, void* addr) { + if (android_fdsan_close_with_tag) { + uint64_t tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, + reinterpret_cast(addr)); + android_fdsan_close_with_tag(fd, tag); + } else { + close(fd); + } + } +#else + static void Close(int fd) { + // Even if close(2) fails with EINTR, the fd will have been closed. + // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone + // else's fd. + // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html + ::close(fd); + } +#endif +}; + +using unique_fd = unique_fd_impl; + +#if !defined(_WIN32) && !defined(__TRUSTY__) + +// Inline functions, so that they can be used header-only. + +// See pipe(2). +// This helper hides the details of converting to unique_fd, and also hides the +// fact that macOS doesn't support O_CLOEXEC or O_NONBLOCK directly. +template +inline bool Pipe(unique_fd_impl* read, unique_fd_impl* write, + int flags = O_CLOEXEC) { + int pipefd[2]; + +#if defined(__linux__) + if (pipe2(pipefd, flags) != 0) { + return false; + } +#else // defined(__APPLE__) + if (flags & ~(O_CLOEXEC | O_NONBLOCK)) { + return false; + } + if (pipe(pipefd) != 0) { + return false; + } + + if (flags & O_CLOEXEC) { + if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 || fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) { + close(pipefd[0]); + close(pipefd[1]); + return false; + } + } + if (flags & O_NONBLOCK) { + if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) != 0 || fcntl(pipefd[1], F_SETFL, O_NONBLOCK) != 0) { + close(pipefd[0]); + close(pipefd[1]); + return false; + } + } +#endif + + read->reset(pipefd[0]); + write->reset(pipefd[1]); + return true; +} + +// See socketpair(2). +// This helper hides the details of converting to unique_fd. +template +inline bool Socketpair(int domain, int type, int protocol, unique_fd_impl* left, + unique_fd_impl* right) { + int sockfd[2]; + if (socketpair(domain, type, protocol, sockfd) != 0) { + return false; + } + left->reset(sockfd[0]); + right->reset(sockfd[1]); + return true; +} + +// See socketpair(2). +// This helper hides the details of converting to unique_fd. +template +inline bool Socketpair(int type, unique_fd_impl* left, unique_fd_impl* right) { + return Socketpair(AF_UNIX, type, 0, left, right); +} + +// See fdopen(3). +// Using fdopen with unique_fd correctly is more annoying than it should be, +// because fdopen doesn't close the file descriptor received upon failure. +inline FILE* Fdopen(unique_fd&& ufd, const char* mode) { + int fd = ufd.release(); + FILE* file = fdopen(fd, mode); + if (!file) { + close(fd); + } + return file; +} + +// See fdopendir(3). +// Using fdopendir with unique_fd correctly is more annoying than it should be, +// because fdopen doesn't close the file descriptor received upon failure. +inline DIR* Fdopendir(unique_fd&& ufd) { + int fd = ufd.release(); + DIR* dir = fdopendir(fd); + if (dir == nullptr) { + close(fd); + } + return dir; +} + +#endif // !defined(_WIN32) && !defined(__TRUSTY__) + +// A wrapper type that can be implicitly constructed from either int or +// unique_fd. This supports cases where you don't actually own the file +// descriptor, and can't take ownership, but are temporarily acting as if +// you're the owner. +// +// One example would be a function that needs to also allow +// STDERR_FILENO, not just a newly-opened fd. Another example would be JNI code +// that's using a file descriptor that's actually owned by a +// ParcelFileDescriptor or whatever on the Java side, but where the JNI code +// would like to enforce this weaker sense of "temporary ownership". +// +// If you think of unique_fd as being like std::string in that represents +// ownership, borrowed_fd is like std::string_view (and int is like const +// char*). +struct borrowed_fd { + /* implicit */ borrowed_fd(int fd) : fd_(fd) {} // NOLINT + template + /* implicit */ borrowed_fd(const unique_fd_impl& ufd) : fd_(ufd.get()) {} // NOLINT + + int get() const { return fd_; } + + bool operator>=(int rhs) const { return get() >= rhs; } + bool operator<(int rhs) const { return get() < rhs; } + bool operator==(int rhs) const { return get() == rhs; } + bool operator!=(int rhs) const { return get() != rhs; } + + private: + int fd_ = -1; +}; +} // namespace base +} // namespace android + +template +int close(const android::base::unique_fd_impl&) + __attribute__((__unavailable__("close called on unique_fd"))); + +template +FILE* fdopen(const android::base::unique_fd_impl&, const char* mode) + __attribute__((__unavailable__("fdopen takes ownership of the fd passed in; either dup the " + "unique_fd, or use android::base::Fdopen to pass ownership"))); + +template +DIR* fdopendir(const android::base::unique_fd_impl&) __attribute__(( + __unavailable__("fdopendir takes ownership of the fd passed in; either dup the " + "unique_fd, or use android::base::Fdopendir to pass ownership"))); diff --git a/app/src/main/cpp/external/AOSP/include/binder/Binder.h b/app/src/main/cpp/external/AOSP/include/binder/Binder.h new file mode 100644 index 0000000..135be89 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/Binder.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2008 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 +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +namespace internal { +class Stability; +} + +class BBinder : public IBinder { +public: + LIBBINDER_EXPORTED BBinder(); + + LIBBINDER_EXPORTED virtual const String16& getInterfaceDescriptor() const; + LIBBINDER_EXPORTED virtual bool isBinderAlive() const; + LIBBINDER_EXPORTED virtual status_t pingBinder(); + LIBBINDER_EXPORTED virtual status_t dump(int fd, const Vector& args); + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0) final; + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t linkToDeath(const sp& recipient, + void* cookie = nullptr, uint32_t flags = 0); + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t unlinkToDeath(const wp& recipient, + void* cookie = nullptr, uint32_t flags = 0, + wp* outRecipient = nullptr); + + LIBBINDER_EXPORTED virtual void* attachObject(const void* objectID, void* object, + void* cleanupCookie, + object_cleanup_func func) final; + LIBBINDER_EXPORTED virtual void* findObject(const void* objectID) const final; + LIBBINDER_EXPORTED virtual void* detachObject(const void* objectID) final; + LIBBINDER_EXPORTED void withLock(const std::function& doWithLock); + LIBBINDER_EXPORTED sp lookupOrCreateWeak(const void* objectID, + IBinder::object_make_func make, + const void* makeArgs); + + LIBBINDER_EXPORTED virtual BBinder* localBinder(); + + LIBBINDER_EXPORTED bool isRequestingSid(); + // This must be called before the object is sent to another process. Not thread safe. + LIBBINDER_EXPORTED void setRequestingSid(bool requestSid); + + LIBBINDER_EXPORTED sp getExtension(); + // This must be called before the object is sent to another process. Not thread safe. + LIBBINDER_EXPORTED void setExtension(const sp& extension); + + // This must be called before the object is sent to another process. Not thread safe. + // + // This function will abort if improper parameters are set. This is like + // sched_setscheduler. However, it sets the minimum scheduling policy + // only for the duration that this specific binder object is handling the + // call in a threadpool. By default, this API is set to SCHED_NORMAL/0. In + // this case, the scheduling priority will not actually be modified from + // binder defaults. See also IPCThreadState::disableBackgroundScheduling. + // + // Appropriate values are: + // SCHED_NORMAL: -20 <= priority <= 19 + // SCHED_RR/SCHED_FIFO: 1 <= priority <= 99 + LIBBINDER_EXPORTED void setMinSchedulerPolicy(int policy, int priority); + LIBBINDER_EXPORTED int getMinSchedulerPolicy(); + LIBBINDER_EXPORTED int getMinSchedulerPriority(); + + // Whether realtime scheduling policies are inherited. + LIBBINDER_EXPORTED bool isInheritRt(); + // This must be called before the object is sent to another process. Not thread safe. + LIBBINDER_EXPORTED void setInheritRt(bool inheritRt); + + LIBBINDER_EXPORTED pid_t getDebugPid(); + + // Whether this binder has been sent to another process. + LIBBINDER_EXPORTED 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. + LIBBINDER_EXPORTED void setParceled(); + + [[nodiscard]] LIBBINDER_EXPORTED status_t setRpcClientDebug(binder::unique_fd clientFd, + const sp& keepAliveBinder); + +protected: + LIBBINDER_EXPORTED virtual ~BBinder(); + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0); + +private: + 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& link); + [[nodiscard]] status_t startRecordingTransactions(const Parcel& data); + [[nodiscard]] status_t stopRecordingTransactions(); + + std::atomic mExtras; + + friend ::android::internal::Stability; + int16_t mStability; + bool mParceled; + bool mRecordingOn; + +#ifdef __LP64__ + int32_t mReserved1; +#endif +}; + +// --------------------------------------------------------------------------- + +class BpRefBase : public virtual RefBase { +protected: + LIBBINDER_EXPORTED explicit BpRefBase(const sp& o); + LIBBINDER_EXPORTED virtual ~BpRefBase(); + LIBBINDER_EXPORTED virtual void onFirstRef(); + LIBBINDER_EXPORTED virtual void onLastStrongRef(const void* id); + LIBBINDER_EXPORTED virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + + LIBBINDER_EXPORTED inline IBinder* remote() const { return mRemote; } + LIBBINDER_EXPORTED inline sp remoteStrong() const { + return sp::fromExisting(mRemote); + } + +private: + BpRefBase(const BpRefBase& o); + BpRefBase& operator=(const BpRefBase& o); + + IBinder* const mRemote; + RefBase::weakref_type* mRefs; + std::atomic mState; +}; + +} // namespace android + +// --------------------------------------------------------------------------- diff --git a/app/src/main/cpp/external/AOSP/include/binder/BpBinder.h b/app/src/main/cpp/external/AOSP/include/binder/BpBinder.h new file mode 100644 index 0000000..935bd8d --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/BpBinder.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005 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 +#include +#include +#include + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class IPCThreadState; +class RpcSession; +class RpcState; +namespace internal { +class Stability; +} +class ProcessState; + +using binder_proxy_limit_callback = std::function; +using binder_proxy_warning_callback = std::function; + +class BpBinder : public IBinder { +public: + /** + * Return value: + * true - this is associated with a socket RpcSession + * false - (usual) binder over e.g. /dev/binder + */ + LIBBINDER_EXPORTED bool isRpcBinder() const; + + LIBBINDER_EXPORTED virtual const String16& getInterfaceDescriptor() const; + LIBBINDER_EXPORTED virtual bool isBinderAlive() const; + LIBBINDER_EXPORTED virtual status_t pingBinder(); + LIBBINDER_EXPORTED virtual status_t dump(int fd, const Vector& args); + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0) final; + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t linkToDeath(const sp& recipient, + void* cookie = nullptr, uint32_t flags = 0); + + // NOLINTNEXTLINE(google-default-arguments) + LIBBINDER_EXPORTED virtual status_t unlinkToDeath(const wp& recipient, + void* cookie = nullptr, uint32_t flags = 0, + wp* outRecipient = nullptr); + + [[nodiscard]] status_t addFrozenStateChangeCallback( + const wp& recipient); + + [[nodiscard]] status_t removeFrozenStateChangeCallback( + const wp& recipient); + + LIBBINDER_EXPORTED virtual void* attachObject(const void* objectID, void* object, + void* cleanupCookie, + object_cleanup_func func) final; + LIBBINDER_EXPORTED virtual void* findObject(const void* objectID) const final; + LIBBINDER_EXPORTED virtual void* detachObject(const void* objectID) final; + LIBBINDER_EXPORTED void withLock(const std::function& doWithLock); + LIBBINDER_EXPORTED sp lookupOrCreateWeak(const void* objectID, + IBinder::object_make_func make, + const void* makeArgs); + LIBBINDER_EXPORTED virtual BpBinder* remoteBinder(); + + LIBBINDER_EXPORTED void sendObituary(); + + LIBBINDER_EXPORTED static uint32_t getBinderProxyCount(uint32_t uid); + LIBBINDER_EXPORTED static void getCountByUid(Vector& uids, Vector& counts); + LIBBINDER_EXPORTED static void enableCountByUid(); + LIBBINDER_EXPORTED static void disableCountByUid(); + LIBBINDER_EXPORTED static void setCountByUidEnabled(bool enable); + LIBBINDER_EXPORTED static void setBinderProxyCountEventCallback( + binder_proxy_limit_callback cbl, binder_proxy_warning_callback cbw); + LIBBINDER_EXPORTED static void setBinderProxyCountWatermarks(int high, int low, int warning); + LIBBINDER_EXPORTED static uint32_t getBinderProxyCount(); + + LIBBINDER_EXPORTED std::optional getDebugBinderHandle() const; + + // Start recording transactions to the unique_fd. + // See RecordedTransaction.h for more details. + LIBBINDER_EXPORTED status_t startRecordingBinder(const binder::unique_fd& fd); + // Stop the current recording. + LIBBINDER_EXPORTED status_t stopRecordingBinder(); + + // Note: This class is not thread safe so protect uses of it when necessary + class ObjectManager { + public: + 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); + sp lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make, + const void* makeArgs); + + private: + ObjectManager(const ObjectManager&); + ObjectManager& operator=(const ObjectManager&); + + struct entry_t { + void* object = nullptr; + void* cleanupCookie = nullptr; + IBinder::object_cleanup_func func = nullptr; + }; + + std::map mObjects; + }; + + class PrivateAccessor { + private: + friend class BpBinder; + friend class ::android::Parcel; + friend class ::android::ProcessState; + friend class ::android::RpcSession; + friend class ::android::RpcState; + friend class ::android::IPCThreadState; + explicit PrivateAccessor(const BpBinder* binder) + : mBinder(binder), mMutableBinder(nullptr) {} + explicit PrivateAccessor(BpBinder* binder) : mBinder(binder), mMutableBinder(binder) {} + + static sp create(int32_t handle, std::function* postTask) { + return BpBinder::create(handle, postTask); + } + static sp create(const sp& session, uint64_t address) { + return BpBinder::create(session, address); + } + + // valid if !isRpcBinder + int32_t binderHandle() const { return mBinder->binderHandle(); } + + // valid if isRpcBinder + uint64_t rpcAddress() const { return mBinder->rpcAddress(); } + const sp& rpcSession() const { return mBinder->rpcSession(); } + + void onFrozenStateChanged(bool isFrozen) { mMutableBinder->onFrozenStateChanged(isFrozen); } + const BpBinder* mBinder; + BpBinder* mMutableBinder; + }; + + LIBBINDER_EXPORTED const PrivateAccessor getPrivateAccessor() const { + return PrivateAccessor(this); + } + + PrivateAccessor getPrivateAccessor() { return PrivateAccessor(this); } + +private: + friend PrivateAccessor; + friend class sp; + + static sp create(int32_t handle, std::function* postTask); + static sp create(const sp& session, uint64_t address); + + struct BinderHandle { + int32_t handle; + }; + struct RpcHandle { + sp session; + uint64_t address; + }; + using Handle = std::variant; + + int32_t binderHandle() const; + uint64_t rpcAddress() const; + const sp& rpcSession() const; + + explicit BpBinder(Handle&& handle); + BpBinder(BinderHandle&& handle, int32_t trackedUid); + explicit BpBinder(RpcHandle&& handle); + + virtual ~BpBinder(); + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + + friend ::android::internal::Stability; + + int32_t mStability; + Handle mHandle; + + struct Obituary { + wp recipient; + void* cookie; + uint32_t flags; + }; + + void onFrozenStateChanged(bool isFrozen); + + struct FrozenStateChange { + bool isFrozen = false; + Vector> callbacks; + bool initialStateReceived = false; + }; + + void reportOneDeath(const Obituary& obit); + bool isDescriptorCached() const; + + mutable RpcMutex mLock; + volatile int32_t mAlive; + volatile int32_t mObitsSent; + Vector* mObituaries; + std::unique_ptr mFrozen; + ObjectManager mObjectMgr; + mutable String16 mDescriptorCache; + int32_t mTrackedUid; + + static RpcMutex sTrackingLock; + static std::unordered_map sTrackingMap; + static int sNumTrackedUids; + static std::atomic_bool sCountByUidEnabled; + static binder_proxy_limit_callback sLimitCallback; + static uint32_t sBinderProxyCountHighWatermark; + static uint32_t sBinderProxyCountLowWatermark; + static bool sBinderProxyThrottleCreate; + static std::unordered_map sLastLimitCallbackMap; + static std::atomic sBinderProxyCount; + static std::atomic sBinderProxyCountWarned; + static binder_proxy_warning_callback sWarningCallback; + static uint32_t sBinderProxyCountWarningWatermark; +}; + +} // namespace android + +// --------------------------------------------------------------------------- diff --git a/app/src/main/cpp/external/AOSP/include/binder/Common.h b/app/src/main/cpp/external/AOSP/include/binder/Common.h new file mode 100644 index 0000000..ed10154 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/Common.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 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 + +// libbinder is built with symbol hidden by default. To add a new symbol to the +// ABI, you must annotate it with this LIBBINDER_EXPORTED macro. When not +// building libbinder (e.g. when another binary includes a libbinder header), +// this macro is a no-op. +// +// Examples: +// +// // Export a function. +// LIBBINDER_EXPORTED void someFunction(); +// +// // Export a subset of the symbols for a class. +// class SomeClassA { +// public: +// LIBBINDER_EXPORTED SomeClassA(); +// +// LIBBINDER_EXPORTED SomeMethod(); +// } +// +// // Export all the symbols for a class, even private symbols. +// class LIBBINDER_EXPORTED SomeClassB {}; +// +// For a more detailed explanation of this strategy, see +// https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html +#if BUILDING_LIBBINDER +#define LIBBINDER_EXPORTED __attribute__((__visibility__("default"))) +#else +#define LIBBINDER_EXPORTED +#endif + +// For stuff that is exported but probably shouldn't be. It behaves the exact +// same way as LIBBINDER_EXPORTED, only exists to help track what we want +// eventually remove. +// +// Needed, at least in part, because the test binaries are using internal +// headers and accessing these symbols directly. +#define LIBBINDER_INTERNAL_EXPORTED LIBBINDER_EXPORTED diff --git a/app/src/main/cpp/external/AOSP/include/binder/IBinder.h b/app/src/main/cpp/external/AOSP/include/binder/IBinder.h new file mode 100644 index 0000000..1ed7c91 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/IBinder.h @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2008 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 +#include +#include +#include +#include +#include + +#include + +// 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 +#define B_PACK_CHARS(c1, c2, c3, c4) \ + ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) +#endif // B_PACK_CHARS + +// --------------------------------------------------------------------------- +namespace android { + +class BBinder; +class BpBinder; +class IInterface; +class Parcel; +class IResultReceiver; +class IShellCallback; + +/** + * Base class and low-level protocol for a remotable object. + * You can derive from this class to create an object for which other + * processes can hold references to it. Communication between processes + * (method calls, property get and set) is down through a low-level + * protocol implemented on top of the transact() API. + */ +class [[clang::lto_visibility_public]] LIBBINDER_EXPORTED IBinder : public virtual RefBase { +public: + enum { + FIRST_CALL_TRANSACTION = 0x00000001, + LAST_CALL_TRANSACTION = 0x00ffffff, + + PING_TRANSACTION = B_PACK_CHARS('_', 'P', 'N', 'G'), + START_RECORDING_TRANSACTION = B_PACK_CHARS('_', 'S', 'R', 'D'), + STOP_RECORDING_TRANSACTION = B_PACK_CHARS('_', 'E', 'R', 'D'), + DUMP_TRANSACTION = B_PACK_CHARS('_', 'D', 'M', 'P'), + SHELL_COMMAND_TRANSACTION = B_PACK_CHARS('_', 'C', 'M', 'D'), + INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'), + 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 + // characters, and callees should exclaim "jolly good message old boy!" + TWEET_TRANSACTION = B_PACK_CHARS('_', 'T', 'W', 'T'), + + // See android.os.IBinder.LIKE_TRANSACTION + // Improve binder self-esteem. + LIKE_TRANSACTION = B_PACK_CHARS('_', 'L', 'I', 'K'), + + // Corresponds to TF_ONE_WAY -- an asynchronous call. + FLAG_ONEWAY = 0x00000001, + + // Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call + // is made + FLAG_CLEAR_BUF = 0x00000020, + + // Private userspace flag for transaction which is being requested from + // a vendor context. + FLAG_PRIVATE_VENDOR = 0x10000000, + }; + + IBinder(); + + /** + * Check if this IBinder implements the interface named by + * @a descriptor. If it does, the base pointer to it is returned, + * which you can safely static_cast<> to the concrete C++ interface. + */ + virtual sp queryLocalInterface(const String16& descriptor); + + /** + * Return the canonical name of the interface provided by this IBinder + * object. + */ + virtual const String16& getInterfaceDescriptor() const = 0; + + /** + * Last known alive status, from last call. May be arbitrarily stale. + * May be incorrect if a service returns an incorrect status code. + */ + virtual bool isBinderAlive() const = 0; + virtual status_t pingBinder() = 0; + virtual status_t dump(int fd, const Vector& args) = 0; + static status_t shellCommand(const sp& target, int in, int out, int err, + Vector& args, const sp& callback, + const sp& resultReceiver); + + /** + * This allows someone to add their own additions to an interface without + * having to modify the original interface. + * + * For instance, imagine if we have this interface: + * interface IFoo { void doFoo(); } + * + * If an unrelated owner (perhaps in a downstream codebase) wants to make a + * change to the interface, they have two options: + * + * A). Historical option that has proven to be BAD! Only the original + * author of an interface should change an interface. If someone + * downstream wants additional functionality, they should not ever + * change the interface or use this method. + * + * BAD TO DO: interface IFoo { BAD TO DO + * BAD TO DO: void doFoo(); BAD TO DO + * BAD TO DO: + void doBar(); // adding a method BAD TO DO + * BAD TO DO: } BAD TO DO + * + * B). Option that this method enables! + * Leave the original interface unchanged (do not change IFoo!). + * Instead, create a new interface in a downstream package: + * + * package com.; // new functionality in a new package + * interface IBar { void doBar(); } + * + * When registering the interface, add: + * sp foo = new MyFoo; // class in AOSP codebase + * sp bar = new MyBar; // custom extension class + * foo->setExtension(bar); // use method in BBinder + * + * Then, clients of IFoo can get this extension: + * sp binder = ...; + * sp foo = interface_cast(binder); // handle if null + * sp barBinder; + * ... handle error ... = binder->getExtension(&barBinder); + * sp bar = interface_cast(barBinder); + * // if bar is null, then there is no extension or a different + * // type of extension + */ + status_t getExtension(sp* out); + + /** + * Dump PID for a binder, for debugging. + */ + 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(binder::unique_fd socketFd, + const sp& keepAliveBinder); + + // NOLINTNEXTLINE(google-default-arguments) + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0) = 0; + + // DeathRecipient is pure abstract, there is no virtual method + // implementation to put in a translation unit in order to silence the + // weak vtables warning. + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wweak-vtables" + #endif + + class DeathRecipient : public virtual RefBase + { + public: + virtual void binderDied(const wp& who) = 0; + }; + + class FrozenStateChangeCallback : public virtual RefBase { + public: + enum class State { + FROZEN, + UNFROZEN, + }; + virtual void onStateChanged(const wp& who, State state) = 0; + }; + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + + /** + * Register the @a recipient for a notification if this binder + * goes away. If this binder object unexpectedly goes away + * (typically because its hosting process has been killed), + * then DeathRecipient::binderDied() will be called with a reference + * to this. + * + * The @a cookie is optional -- if non-NULL, it should be a + * memory address that you own (that is, you know it is unique). + * + * @note When all references to the binder being linked to are dropped, the + * recipient is automatically unlinked. So, you must hold onto a binder in + * order to receive death notifications about it. + * + * @note You will only receive death notifications for remote binders, + * as local binders by definition can't die without you dying as well. + * Trying to use this function on a local binder will result in an + * INVALID_OPERATION code being returned and nothing happening. + * + * @note This link always holds a weak reference to its recipient. + * + * @note You will only receive a weak reference to the dead + * binder. You should not try to promote this to a strong reference. + * (Nor should you need to, as there is nothing useful you can + * directly do with it now that it has passed on.) + */ + // NOLINTNEXTLINE(google-default-arguments) + virtual status_t linkToDeath(const sp& recipient, + void* cookie = nullptr, + uint32_t flags = 0) = 0; + + /** + * Remove a previously registered death notification. + * The @a recipient will no longer be called if this object + * dies. The @a cookie is optional. If non-NULL, you can + * supply a NULL @a recipient, and the recipient previously + * added with that cookie will be unlinked. + * + * If the binder is dead, this will return DEAD_OBJECT. Deleting + * the object will also unlink all death recipients. + */ + // NOLINTNEXTLINE(google-default-arguments) + virtual status_t unlinkToDeath( const wp& recipient, + void* cookie = nullptr, + uint32_t flags = 0, + wp* outRecipient = nullptr) = 0; + + /** + * addFrozenStateChangeCallback provides a callback mechanism to notify + * about process frozen/unfrozen events. Upon registration and any + * subsequent state changes, the callback is invoked with the latest process + * frozen state. + * + * If the listener process (the one using this API) is itself frozen, state + * change events might be combined into a single one with the latest state. + * (meaning 'frozen, unfrozen' might just be 'unfrozen'). This single event + * would then be delivered when the listener process becomes unfrozen. + * Similarly, if an event happens before the previous event is consumed, + * they might be combined. This means the callback might not be called for + * every single state change, so don't rely on this API to count how many + * times the state has changed. + * + * @note When all references to the binder are dropped, the callback is + * automatically removed. So, you must hold onto a binder in order to + * receive notifications about it. + * + * @note You will only receive freeze notifications for remote binders, as + * local binders by definition can't be frozen without you being frozen as + * well. Trying to use this function on a local binder will result in an + * INVALID_OPERATION code being returned and nothing happening. + * + * @note This binder always holds a weak reference to the callback. + * + * @note You will only receive a weak reference to the binder object. You + * should not try to promote this to a strong reference. (Nor should you + * need to, as there is nothing useful you can directly do with it now that + * it has passed on.) + */ + [[nodiscard]] status_t addFrozenStateChangeCallback( + const wp& callback); + + /** + * Remove a previously registered freeze callback. + * The @a callback will no longer be called if this object + * changes its frozen state. + */ + [[nodiscard]] status_t removeFrozenStateChangeCallback( + const wp& callback); + + virtual bool checkSubclass(const void* subclassID) const; + + typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); + + /** + * This object is attached for the lifetime of this binder object. When + * this binder object is destructed, the cleanup function of all attached + * 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). + */ + [[nodiscard]] virtual void* attachObject(const void* objectID, void* object, + void* cleanupCookie, object_cleanup_func func) = 0; + /** + * Returns object attached with attachObject. + */ + [[nodiscard]] virtual void* findObject(const void* objectID) const = 0; + /** + * Returns object attached with attachObject, and detaches it. This does not + * delete the object. + */ + [[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& doWithLock); + + virtual BBinder* localBinder(); + virtual BpBinder* remoteBinder(); + typedef sp (*object_make_func)(const void* makeArgs); + sp lookupOrCreateWeak(const void* objectID, object_make_func make, + const void* makeArgs); + +protected: + virtual ~IBinder(); + +private: +}; + +} // namespace android + +// --------------------------------------------------------------------------- diff --git a/app/src/main/cpp/external/AOSP/include/binder/IInterface.h b/app/src/main/cpp/external/AOSP/include/binder/IInterface.h new file mode 100644 index 0000000..993ad82 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/IInterface.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2005 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 +#include + +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class LIBBINDER_EXPORTED IInterface : public virtual RefBase { +public: + IInterface(); + static sp asBinder(const IInterface*); + static sp asBinder(const sp&); + +protected: + virtual ~IInterface(); + virtual IBinder* onAsBinder() = 0; +}; + +// ---------------------------------------------------------------------- + +/** + * If this is a local object and the descriptor matches, this will return the + * actual local object which is implementing the interface. Otherwise, this will + * return a proxy to the interface without checking the interface descriptor. + * This means that subsequent calls may fail with BAD_TYPE. + */ +template +inline sp interface_cast(const sp& obj) +{ + return INTERFACE::asInterface(obj); +} + +/** + * This is the same as interface_cast, except that it always checks to make sure + * the descriptor matches, and if it doesn't match, it will return nullptr. + */ +template +inline sp checked_interface_cast(const sp& obj) +{ + if (obj->getInterfaceDescriptor() != INTERFACE::descriptor) { + return nullptr; + } + + return interface_cast(obj); +} + +// ---------------------------------------------------------------------- + +template +class LIBBINDER_EXPORTED BnInterface : public INTERFACE, public BBinder { +public: + virtual sp queryLocalInterface(const String16& _descriptor); + virtual const String16& getInterfaceDescriptor() const; + typedef INTERFACE BaseInterface; + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +template +class LIBBINDER_EXPORTED BpInterface : public INTERFACE, public BpRefBase { +public: + explicit BpInterface(const sp& remote); + typedef INTERFACE BaseInterface; + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +#define DECLARE_META_INTERFACE(INTERFACE) \ +public: \ + static const ::android::String16 descriptor; \ + static ::android::sp asInterface(const ::android::sp<::android::IBinder>& obj); \ + virtual const ::android::String16& getInterfaceDescriptor() const; \ + I##INTERFACE(); \ + virtual ~I##INTERFACE(); \ + static bool setDefaultImpl(::android::sp impl); \ + static const ::android::sp& getDefaultImpl(); \ + \ +private: \ + static ::android::sp default_impl; \ + \ +public: + +#define __IINTF_CONCAT(x, y) (x ## y) + +#ifndef DO_NOT_CHECK_MANUAL_BINDER_INTERFACES + +#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + static_assert(internal::allowedManualInterface(NAME), \ + "b/64223827: Manually written binder interfaces are " \ + "considered error prone and frequently have bugs. " \ + "The preferred way to add interfaces is to define " \ + "an .aidl file to auto-generate the interface. If " \ + "an interface must be manually written, add its " \ + "name to the allowlist."); \ + DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) + +#else + +#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + +#endif + +// Macro to be used by both IMPLEMENT_META_INTERFACE and IMPLEMENT_META_NESTED_INTERFACE +#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(ITYPE, INAME, BPTYPE) \ + const ::android::String16& ITYPE::getInterfaceDescriptor() const { return ITYPE::descriptor; } \ + ::android::sp ITYPE::asInterface(const ::android::sp<::android::IBinder>& obj) { \ + ::android::sp intr; \ + if (obj != nullptr) { \ + intr = ::android::sp::cast(obj->queryLocalInterface(ITYPE::descriptor)); \ + if (intr == nullptr) { \ + intr = ::android::sp::make(obj); \ + } \ + } \ + return intr; \ + } \ + ::android::sp ITYPE::default_impl; \ + bool ITYPE::setDefaultImpl(::android::sp impl) { \ + /* Only one user of this interface can use this function */ \ + /* at a time. This is a heuristic to detect if two different */ \ + /* users in the same process use this function. */ \ + assert(!ITYPE::default_impl); \ + if (impl) { \ + ITYPE::default_impl = std::move(impl); \ + return true; \ + } \ + return false; \ + } \ + const ::android::sp& ITYPE::getDefaultImpl() { return ITYPE::default_impl; } \ + ITYPE::INAME() {} \ + ITYPE::~INAME() {} + +// Macro for an interface type. +#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + const ::android::StaticString16 I##INTERFACE##_descriptor_static_str16( \ + __IINTF_CONCAT(u, NAME)); \ + const ::android::String16 I##INTERFACE::descriptor(I##INTERFACE##_descriptor_static_str16); \ + DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(I##INTERFACE, I##INTERFACE, Bp##INTERFACE) + +// Macro for "nested" interface type. +// For example, +// class Parent .. { class INested .. { }; }; +// DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE(Parent, Nested, "Parent.INested") +#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE(PARENT, INTERFACE, NAME) \ + const ::android::String16 PARENT::I##INTERFACE::descriptor(NAME); \ + DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(PARENT::I##INTERFACE, I##INTERFACE, \ + PARENT::Bp##INTERFACE) + +#define CHECK_INTERFACE(interface, data, reply) \ + do { \ + if (!(data).checkInterface(this)) { return PERMISSION_DENIED; } \ + } while (false) \ + + +// ---------------------------------------------------------------------- +// No user-serviceable parts after this... + +template +inline sp BnInterface::queryLocalInterface( + const String16& _descriptor) +{ + if (_descriptor == INTERFACE::descriptor) return sp::fromExisting(this); + return nullptr; +} + +template +inline const String16& BnInterface::getInterfaceDescriptor() const +{ + return INTERFACE::getInterfaceDescriptor(); +} + +template +IBinder* BnInterface::onAsBinder() +{ + return this; +} + +template +inline BpInterface::BpInterface(const sp& remote) + : BpRefBase(remote) +{ +} + +template +inline IBinder* BpInterface::onAsBinder() +{ + return remote(); +} + +// ---------------------------------------------------------------------- + +namespace internal { +constexpr const char* const kManualInterfaces[] = { + "android.app.IActivityManager", + "android.app.IUidObserver", + "android.gfx.tests.ICallback", + "android.gfx.tests.IIPCTest", + "android.gfx.tests.ISafeInterfaceTest", + "android.graphicsenv.IGpuService", + "android.gui.IConsumerListener", + "android.gui.IGraphicBufferConsumer", + "android.gui.ITransactionComposerListener", + "android.gui.SensorEventConnection", + "android.gui.SensorServer", + "android.hardware.ICamera", + "android.hardware.ICameraClient", + "android.hardware.ICameraRecordingProxy", + "android.hardware.ICameraRecordingProxyListener", + "android.hardware.IOMXObserver", + "android.hardware.IStreamListener", + "android.hardware.IStreamSource", + "android.media.IAudioService", + "android.media.IDataSource", + "android.media.IMediaCodecList", + "android.media.IMediaExtractor", + "android.media.IMediaHTTPConnection", + "android.media.IMediaHTTPService", + "android.media.IMediaLogService", + "android.media.IMediaMetadataRetriever", + "android.media.IMediaPlayer", + "android.media.IMediaPlayerClient", + "android.media.IMediaPlayerService", + "android.media.IMediaRecorder", + "android.media.IMediaRecorderClient", + "android.media.IMediaResourceMonitor", + "android.media.IMediaSource", + "android.media.IRemoteDisplay", + "android.media.IRemoteDisplayClient", + "android.os.IPermissionController", + "android.os.IProcessInfoService", + "android.os.ISchedulingPolicyService", + "android.os.storage.IObbActionListener", + "android.os.storage.IStorageEventListener", + "android.os.storage.IStorageManager", + "android.os.storage.IStorageShutdownObserver", + "android.ui.ISurfaceComposer", + "android.utils.IMemory", + "android.utils.IMemoryHeap", + "com.android.car.procfsinspector.IProcfsInspector", + "com.android.internal.app.IAppOpsService", + "com.android.internal.app.IBatteryStats", + "com.android.internal.os.IResultReceiver", + "com.android.internal.os.IShellCallback", + "drm.IDrmManagerService", + "drm.IDrmServiceListener", + nullptr, +}; + +constexpr const char* const kDownstreamManualInterfaces[] = { + // Add downstream interfaces here. + nullptr, +}; + +constexpr bool equals(const char* a, const char* b) { + if (*a != *b) return false; + if (*a == '\0') return true; + return equals(a + 1, b + 1); +} + +constexpr bool inList(const char* a, const char* const* allowlist) { + if (*allowlist == nullptr) return false; + if (equals(a, *allowlist)) return true; + return inList(a, allowlist + 1); +} + +constexpr bool allowedManualInterface(const char* name) { + return inList(name, kManualInterfaces) || + inList(name, kDownstreamManualInterfaces); +} + +} // namespace internal +} // namespace android diff --git a/app/src/main/cpp/external/AOSP/include/binder/IPCThreadState.h b/app/src/main/cpp/external/AOSP/include/binder/IPCThreadState.h new file mode 100644 index 0000000..f7465e2 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/IPCThreadState.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2005 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 +#include +#include +#include +#include + +#if defined(_WIN32) +typedef int uid_t; +#endif + +// --------------------------------------------------------------------------- +namespace android { + +/** + * Kernel binder thread state. All operations here refer to kernel binder. This + * object is allocated per-thread. + */ +class IPCThreadState { +public: + using CallRestriction = ProcessState::CallRestriction; + + LIBBINDER_EXPORTED static IPCThreadState* self(); + LIBBINDER_EXPORTED static IPCThreadState* selfOrNull(); // self(), but won't instantiate + + // Freeze or unfreeze the binder interface to a specific process. When freezing, this method + // will block up to timeout_ms to process pending transactions directed to pid. Unfreeze + // is immediate. Transactions to processes frozen via this method won't be delivered and the + // driver will return BR_FROZEN_REPLY to the client sending them. After unfreeze, + // transactions will be delivered normally. + // + // pid: id for the process for which the binder interface is to be frozen + // enable: freeze (true) or unfreeze (false) + // timeout_ms: maximum time this function is allowed to block the caller waiting for pending + // binder transactions to be processed. + // + // returns: 0 in case of success, a value < 0 in case of error + LIBBINDER_EXPORTED static status_t freeze(pid_t pid, bool enabled, uint32_t timeout_ms); + + // Provide information about the state of a frozen process + LIBBINDER_EXPORTED static status_t getProcessFreezeInfo(pid_t pid, uint32_t* sync_received, + uint32_t* async_received); + + LIBBINDER_EXPORTED status_t clearLastError(); + + /** + * Returns the PID of the process which has made the current binder + * call. If not in a binder call, this will return getpid. + * + * Warning do not use this as a security identifier! PID is unreliable + * as it may be re-used. This should mostly be used for debugging. + * + * oneway transactions do not receive PID. Even if you expect + * a transaction to be synchronous, a misbehaving client could send it + * as an asynchronous call and result in a 0 PID here. Additionally, if + * there is a race and the calling process dies, the PID may still be + * 0 for a synchronous call. + */ + [[nodiscard]] LIBBINDER_EXPORTED pid_t getCallingPid() const; + + /** + * Returns the SELinux security identifier of the process which has + * made the current binder call. If not in a binder call this will + * return nullptr. If this isn't requested with + * Binder::setRequestingSid, it will also return nullptr. + * + * 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. + */ + [[nodiscard]] LIBBINDER_EXPORTED 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. + */ + [[nodiscard]] LIBBINDER_EXPORTED 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; + }; + LIBBINDER_EXPORTED const SpGuard* pushGetCallingSpGuard(const SpGuard* guard); + LIBBINDER_EXPORTED 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. + */ + LIBBINDER_EXPORTED void checkContextIsBinderForUse(const char* use) const; + + LIBBINDER_EXPORTED void setStrictModePolicy(int32_t policy); + LIBBINDER_EXPORTED int32_t getStrictModePolicy() const; + + // See Binder#setCallingWorkSourceUid in Binder.java. + LIBBINDER_EXPORTED int64_t setCallingWorkSourceUid(uid_t uid); + // Internal only. Use setCallingWorkSourceUid(uid) instead. + LIBBINDER_EXPORTED int64_t setCallingWorkSourceUidWithoutPropagation(uid_t uid); + // See Binder#getCallingWorkSourceUid in Binder.java. + LIBBINDER_EXPORTED uid_t getCallingWorkSourceUid() const; + // See Binder#clearCallingWorkSource in Binder.java. + LIBBINDER_EXPORTED int64_t clearCallingWorkSource(); + // See Binder#restoreCallingWorkSource in Binder.java. + LIBBINDER_EXPORTED void restoreCallingWorkSource(int64_t token); + LIBBINDER_EXPORTED void clearPropagateWorkSource(); + LIBBINDER_EXPORTED bool shouldPropagateWorkSource() const; + + LIBBINDER_EXPORTED void setLastTransactionBinderFlags(int32_t flags); + LIBBINDER_EXPORTED int32_t getLastTransactionBinderFlags() const; + + LIBBINDER_EXPORTED void setCallRestriction(CallRestriction restriction); + LIBBINDER_EXPORTED CallRestriction getCallRestriction() const; + + LIBBINDER_EXPORTED int64_t clearCallingIdentity(); + // Restores PID/UID (not SID) + LIBBINDER_EXPORTED void restoreCallingIdentity(int64_t token); + LIBBINDER_EXPORTED bool hasExplicitIdentity(); + + // For main functions - dangerous for libraries to use + LIBBINDER_EXPORTED status_t setupPolling(int* fd); + LIBBINDER_EXPORTED status_t handlePolledCommands(); + LIBBINDER_EXPORTED void flushCommands(); + LIBBINDER_EXPORTED bool flushIfNeeded(); + + // Adds the current thread into the binder threadpool. + // + // This is in addition to any threads which are started + // with startThreadPool. Libraries should not call this + // function, as they may be loaded into processes which + // try to configure the threadpool differently. + LIBBINDER_EXPORTED void joinThreadPool(bool isMain = true); + + // Stop the local process. + LIBBINDER_EXPORTED void stopProcess(bool immediate = true); + + LIBBINDER_EXPORTED status_t transact(int32_t handle, uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags); + + LIBBINDER_EXPORTED void incStrongHandle(int32_t handle, BpBinder* proxy); + LIBBINDER_EXPORTED void decStrongHandle(int32_t handle); + LIBBINDER_EXPORTED void incWeakHandle(int32_t handle, BpBinder* proxy); + LIBBINDER_EXPORTED void decWeakHandle(int32_t handle); + LIBBINDER_EXPORTED status_t attemptIncStrongHandle(int32_t handle); + LIBBINDER_EXPORTED static void expungeHandle(int32_t handle, IBinder* binder); + LIBBINDER_EXPORTED status_t requestDeathNotification(int32_t handle, BpBinder* proxy); + LIBBINDER_EXPORTED status_t clearDeathNotification(int32_t handle, BpBinder* proxy); + [[nodiscard]] status_t addFrozenStateChangeCallback(int32_t handle, BpBinder* proxy); + [[nodiscard]] status_t removeFrozenStateChangeCallback(int32_t handle, BpBinder* proxy); + + LIBBINDER_EXPORTED static void shutdown(); + + // Call this to disable switching threads to background scheduling when + // receiving incoming IPC calls. This is specifically here for the + // Android system process, since it expects to have background apps calling + // in to it but doesn't want to acquire locks in its services while in + // the background. + LIBBINDER_EXPORTED static void disableBackgroundScheduling(bool disable); + LIBBINDER_EXPORTED bool backgroundSchedulingDisabled(); + + // Call blocks until the number of executing binder threads is less than + // the maximum number of binder threads threads allowed for this process. + LIBBINDER_EXPORTED void blockUntilThreadAvailable(); + + // Service manager registration + LIBBINDER_EXPORTED void setTheContextObject(const sp& obj); + + // WARNING: DO NOT USE THIS API + // + // Returns a pointer to the stack from the last time a transaction + // was initiated by the kernel. Used to compare when making nested + // calls between multiple different transports. + LIBBINDER_EXPORTED const void* getServingStackPointer() const; + + // The work source represents the UID of the process we should attribute the transaction + // to. We use -1 to specify that the work source was not set using #setWorkSource. + // + // This constant needs to be kept in sync with Binder.UNSET_WORKSOURCE from the Java + // side. + LIBBINDER_EXPORTED static const int32_t kUnsetWorkSource = -1; + +private: + IPCThreadState(); + ~IPCThreadState(); + + [[nodiscard]] status_t sendReply(const Parcel& reply, uint32_t flags); + [[nodiscard]] status_t waitForResponse(Parcel* reply, status_t* acquireResult = nullptr); + [[nodiscard]] status_t talkWithDriver(bool doReceive = true); + [[nodiscard]] status_t writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, + uint32_t code, const Parcel& data, + status_t* statusBuffer); + [[nodiscard]] status_t getAndExecuteCommand(); + [[nodiscard]] status_t executeCommand(int32_t command); + void processPendingDerefs(); + void processPostWriteDerefs(); + + void clearCaller(); + + static void threadDestructor(void *st); + static void freeBuffer(const uint8_t* data, size_t dataSize, const binder_size_t* objects, + size_t objectsSize); + static void logExtendedError(); + + const sp mProcess; + Vector mPendingStrongDerefs; + Vector mPendingWeakDerefs; + Vector mPostWriteStrongDerefs; + Vector mPostWriteWeakDerefs; + Parcel mIn; + Parcel mOut; + status_t mLastError; + const void* mServingStackPointer; + const SpGuard* mServingStackPointerGuard; + pid_t mCallingPid; + const char* mCallingSid; + uid_t mCallingUid; + // The UID of the process who is responsible for this transaction. + // This is used for resource attribution. + int32_t mWorkSource; + // Whether the work source should be propagated. + bool mPropagateWorkSource; + bool mIsLooper; + bool mIsFlushing; + bool mHasExplicitIdentity; + int32_t mStrictModePolicy; + int32_t mLastTransactionBinderFlags; + CallRestriction mCallRestriction; +}; + +} // namespace android + +// --------------------------------------------------------------------------- diff --git a/app/src/main/cpp/external/AOSP/include/binder/IServiceManager.h b/app/src/main/cpp/external/AOSP/include/binder/IServiceManager.h new file mode 100644 index 0000000..d248f22 --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/IServiceManager.h @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2005 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 +#include +// Trusty has its own definition of socket APIs from trusty_ipc.h +#ifndef __TRUSTY__ +#include +#endif // __TRUSTY__ +#include +#include +#include +#include + +namespace android { + +/** + * Service manager for C++ services. + * + * IInterface is only for legacy ABI compatibility + */ +class LIBBINDER_EXPORTED IServiceManager : public IInterface { +public: + // for ABI compatibility + virtual const String16& getInterfaceDescriptor() const; + + IServiceManager(); + virtual ~IServiceManager(); + + /** + * Must match values in IServiceManager.aidl + */ + /* Allows services to dump sections according to priorities. */ + static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0; + static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1; + static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2; + /** + * Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the + * same priority as NORMAL priority but the services are not called with dump priority + * arguments. + */ + static const int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3; + static const int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL | + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT; + static const int DUMP_FLAG_PROTO = 1 << 4; + + /** + * Retrieve an existing service, blocking for a few seconds if it doesn't yet exist. This + * does polling. A more efficient way to make sure you unblock as soon as the service is + * available is to use waitForService or to use service notifications. + * + * Warning: when using this API, typically, you should call it in a loop. It's dangerous to + * assume that nullptr could mean that the service is not available. The service could just + * be starting. Generally, whether a service exists, this information should be declared + * externally (for instance, an Android feature might imply the existence of a service, + * a system property, or in the case of services in the VINTF manifest, it can be checked + * with isDeclared). + */ + [[deprecated("this polls for 5s, prefer waitForService or checkService")]] + virtual sp getService(const String16& name) const = 0; + + /** + * Retrieve an existing service, non-blocking. + */ + virtual sp checkService( const String16& name) const = 0; + + /** + * Register a service. + * + * Note: + * This status_t return value may be an exception code from an underlying + * Status type that doesn't have a representive error code in + * utils/Errors.h. + * One example of this is a return value of -7 + * (Status::Exception::EX_UNSUPPORTED_OPERATION) when the service manager + * process is not installed on the device when addService is called. + */ + // NOLINTNEXTLINE(google-default-arguments) + virtual status_t addService(const String16& name, const sp& service, + bool allowIsolated = false, + int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0; + + /** + * Return list of all existing services. + */ + // NOLINTNEXTLINE(google-default-arguments) + virtual Vector listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0; + + /** + * Efficiently wait for a service. + * + * Returns nullptr only for permission problem or fatal error. + */ + virtual sp waitForService(const String16& name) = 0; + + /** + * Check if a service is declared (e.g. VINTF manifest). + * + * If this returns true, waitForService should always be able to return the + * service. + */ + virtual bool isDeclared(const String16& name) = 0; + + /** + * Get all instances of a service as declared in the VINTF manifest + */ + virtual Vector getDeclaredInstances(const String16& interface) = 0; + + /** + * If this instance is updatable via an APEX, returns the APEX with which + * this can be updated. + */ + virtual std::optional updatableViaApex(const String16& name) = 0; + + /** + * Returns all instances which are updatable via the APEX. Instance names are fully qualified + * like `pack.age.IFoo/default`. + */ + virtual Vector getUpdatableNames(const String16& apexName) = 0; + + /** + * If this instance has declared remote connection information, returns + * the ConnectionInfo. + */ + struct ConnectionInfo { + std::string ipAddress; + unsigned int port; + }; + virtual std::optional getConnectionInfo(const String16& name) = 0; + + struct LocalRegistrationCallback : public virtual RefBase { + virtual void onServiceRegistration(const String16& instance, const sp& binder) = 0; + virtual ~LocalRegistrationCallback() {} + }; + + virtual status_t registerForNotifications(const String16& name, + const sp& callback) = 0; + + virtual status_t unregisterForNotifications(const String16& name, + const sp& callback) = 0; + + struct ServiceDebugInfo { + std::string name; + int pid; + }; + virtual std::vector getServiceDebugInfo() = 0; + + /** + * Directly enable or disable caching binder during addService calls. + * Only used for testing. This is enabled by default. + */ + virtual void enableAddServiceCache(bool value) = 0; +}; + +LIBBINDER_EXPORTED sp defaultServiceManager(); + +/** + * Directly set the default service manager. Only used for testing. + * Note that the caller is responsible for caling this method + * *before* any call to defaultServiceManager(); if the latter is + * called first, setDefaultServiceManager() will abort. + */ +LIBBINDER_EXPORTED void setDefaultServiceManager(const sp& sm); + +template +sp waitForService(const String16& name) { + const sp sm = defaultServiceManager(); + return interface_cast(sm->waitForService(name)); +} + +template +sp waitForDeclaredService(const String16& name) { + const sp sm = defaultServiceManager(); + if (!sm->isDeclared(name)) return nullptr; + return interface_cast(sm->waitForService(name)); +} + +template +sp checkDeclaredService(const String16& name) { + const sp sm = defaultServiceManager(); + if (!sm->isDeclared(name)) return nullptr; + return interface_cast(sm->checkService(name)); +} + +template +sp waitForVintfService( + const String16& instance = String16("default")) { + return waitForDeclaredService( + INTERFACE::descriptor + String16("/") + instance); +} + +template +sp checkVintfService( + const String16& instance = String16("default")) { + return checkDeclaredService( + INTERFACE::descriptor + String16("/") + instance); +} + +template +status_t getService(const String16& name, sp* outService) +{ + const sp sm = defaultServiceManager(); + if (sm != nullptr) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + *outService = interface_cast(sm->getService(name)); +#pragma clang diagnostic pop // getService deprecation + if ((*outService) != nullptr) return NO_ERROR; + } + return NAME_NOT_FOUND; +} + +LIBBINDER_EXPORTED void* openDeclaredPassthroughHal(const String16& interface, + const String16& instance, int flag); + +LIBBINDER_EXPORTED bool checkCallingPermission(const String16& permission); +LIBBINDER_EXPORTED bool checkCallingPermission(const String16& permission, int32_t* outPid, + int32_t* outUid); +LIBBINDER_EXPORTED bool checkPermission(const String16& permission, pid_t pid, uid_t uid, + bool logPermissionFailure = true); + +// ---------------------------------------------------------------------- +// Trusty's definition of the socket APIs does not include sockaddr types +#ifndef __TRUSTY__ +typedef std::function + RpcSocketAddressProvider; + +/** + * This callback provides a way for clients to get access to remote services by + * providing an Accessor object from libbinder that can connect to the remote + * service over sockets. + * + * \param instance name of the service that the callback will provide an + * Accessor for. The provided accessor will be used to set up a client + * RPC connection in libbinder in order to return a binder for the + * associated remote service. + * + * \return IBinder of the Accessor object that libbinder implements. + * nullptr if the provider callback doesn't know how to reach the + * service or doesn't want to provide access for any other reason. + */ +typedef std::function(const String16& instance)> RpcAccessorProvider; + +class AccessorProvider; + +/** + * Register a RpcAccessorProvider for the service manager APIs. + * + * \param instances that the RpcAccessorProvider knows about and can provide an + * Accessor for. + * \param provider callback that generates Accessors. + * + * \return A pointer used as a recept for the successful addition of the + * AccessorProvider. This is needed to unregister it later. + */ +[[nodiscard]] LIBBINDER_EXPORTED std::weak_ptr addAccessorProvider( + std::set&& instances, RpcAccessorProvider&& providerCallback); + +/** + * Remove an accessor provider using the pointer provided by addAccessorProvider + * along with the cookie pointer that was used. + * + * \param provider cookie that was returned by addAccessorProvider to keep track + * of this instance. + */ +[[nodiscard]] LIBBINDER_EXPORTED status_t +removeAccessorProvider(std::weak_ptr provider); + +/** + * Create an Accessor associated with a service that can create a socket connection based + * on the connection info from the supplied RpcSocketAddressProvider. + * + * \param instance name of the service that this Accessor is associated with + * \param connectionInfoProvider a callback that returns connection info for + * connecting to the service. + * \return the binder of the IAccessor implementation from libbinder + */ +LIBBINDER_EXPORTED sp createAccessor(const String16& instance, + RpcSocketAddressProvider&& connectionInfoProvider); + +/** + * Check to make sure this binder is the expected binder that is an IAccessor + * associated with a specific instance. + * + * This helper function exists to avoid adding the IAccessor type to + * libbinder_ndk. + * + * \param instance name of the service that this Accessor should be associated with + * \param binder to validate + * + * \return OK if the binder is an IAccessor for `instance` + */ +LIBBINDER_EXPORTED status_t validateAccessor(const String16& instance, const sp& binder); + +/** + * Have libbinder wrap this IAccessor binder in an IAccessorDelegator and return + * it. + * + * This is required only in very specific situations when the process that has + * permissions to connect the to RPC service's socket and create the FD for it + * is in a separate process from this process that wants to service the Accessor + * binder and the communication between these two processes is binder RPC. This + * is needed because the binder passed over the binder RPC connection can not be + * used as a kernel binder, and needs to be wrapped by a kernel binder that can + * then be registered with service manager. + * + * \param instance name of the Accessor. + * \param binder to wrap in a Delegator and register with service manager. + * \param outDelegator the wrapped kernel binder for IAccessorDelegator + * + * \return OK if the binder is an IAccessor for `instance` and the delegator was + * successfully created. + */ +LIBBINDER_EXPORTED status_t delegateAccessor(const String16& name, const sp& accessor, + sp* delegator); +#endif // __TRUSTY__ + +#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. +// +// For each returned binder object, at most |maxOutgoingConnections| outgoing connections are +// instantiated, depending on how many the service on the device is configured with. +// Hence, only |maxOutgoingConnections| calls can be made simultaneously. +// See also RpcSession::setMaxOutgoingConnections. +struct RpcDelegateServiceManagerOptions { + std::optional maxOutgoingConnections; +}; +LIBBINDER_EXPORTED sp createRpcDelegateServiceManager( + const RpcDelegateServiceManagerOptions& options); +#endif + +} // namespace android diff --git a/app/src/main/cpp/external/AOSP/include/binder/Parcel.h b/app/src/main/cpp/external/AOSP/include/binder/Parcel.h new file mode 100644 index 0000000..6c4c6fe --- /dev/null +++ b/app/src/main/cpp/external/AOSP/include/binder/Parcel.h @@ -0,0 +1,1674 @@ +/* + * Copyright (C) 2005 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 +#include +#include // for legacy reasons +#include +#include +#include +#include +#include + +#include +#ifndef BINDER_DISABLE_NATIVE_HANDLE +#include +#endif +#include +#include +#include +#include + +#include +#include +#include + +//NOLINTNEXTLINE(google-runtime-int) b/173188702 +typedef unsigned long long binder_size_t; + +struct flat_binder_object; + +// --------------------------------------------------------------------------- +namespace android { + +template class Flattenable; +template class LightFlattenable; +class IBinder; +class IPCThreadState; +class ProcessState; +class RpcSession; +class String8; +class TextOutput; +namespace binder { +class Status; +namespace debug { +class RecordedTransaction; +} +} + +class Parcel { + friend class IPCThreadState; + friend class RpcState; + +public: + class ReadableBlob; + class WritableBlob; + + LIBBINDER_EXPORTED Parcel(); + LIBBINDER_EXPORTED ~Parcel(); + + LIBBINDER_EXPORTED const uint8_t* data() const; + LIBBINDER_EXPORTED size_t dataSize() const; + LIBBINDER_EXPORTED size_t dataAvail() const; + LIBBINDER_EXPORTED size_t dataPosition() const; + LIBBINDER_EXPORTED size_t dataCapacity() const; + LIBBINDER_EXPORTED size_t dataBufferSize() const; + + LIBBINDER_EXPORTED status_t setDataSize(size_t size); + + // this must only be used to set a data position that was previously returned from + // dataPosition(). If writes are made, the exact same types of writes must be made (e.g. + // auto i = p.dataPosition(); p.writeInt32(0); p.setDataPosition(i); p.writeInt32(1);). + // Writing over objects, such as file descriptors and binders, is not supported. + LIBBINDER_EXPORTED void setDataPosition(size_t pos) const; + LIBBINDER_EXPORTED status_t setDataCapacity(size_t size); + + LIBBINDER_EXPORTED status_t setData(const uint8_t* buffer, size_t len); + + LIBBINDER_EXPORTED status_t appendFrom(const Parcel* parcel, size_t start, size_t len); + + LIBBINDER_EXPORTED int compareData(const Parcel& other) const; + LIBBINDER_EXPORTED status_t compareDataInRange(size_t thisOffset, const Parcel& other, + size_t otherOffset, size_t length, + int* result) const; + + LIBBINDER_EXPORTED bool allowFds() const; + LIBBINDER_EXPORTED bool pushAllowFds(bool allowFds); + LIBBINDER_EXPORTED void restoreAllowFds(bool lastValue); + + LIBBINDER_EXPORTED bool hasFileDescriptors() const; + LIBBINDER_EXPORTED status_t hasBinders(bool* result) const; + LIBBINDER_EXPORTED status_t hasFileDescriptorsInRange(size_t offset, size_t length, + bool* result) const; + LIBBINDER_EXPORTED status_t hasBindersInRange(size_t offset, size_t length, bool* result) const; + + // returns all binder objects in the Parcel + LIBBINDER_EXPORTED std::vector> debugReadAllStrongBinders() const; + // returns all file descriptors in the Parcel + // does not dup + LIBBINDER_EXPORTED std::vector debugReadAllFileDescriptors() const; + + // Zeros data when reallocating. Other mitigations may be added + // in the future. + // + // WARNING: some read methods may make additional copies of data. + // In order to verify this, heap dumps should be used. + LIBBINDER_EXPORTED void markSensitive() const; + + // For a 'data' Parcel, this should mark the Parcel as being prepared for a + // transaction on this specific binder object. Based on this, the format of + // the wire binder protocol may change (data is written differently when it + // is for an RPC transaction). + LIBBINDER_EXPORTED void markForBinder(const sp& binder); + + // Whenever possible, markForBinder should be preferred. This method is + // called automatically on reply Parcels for RPC transactions. + LIBBINDER_EXPORTED void markForRpc(const sp& session); + + // Whether this Parcel is written for RPC transactions (after calls to + // markForBinder or markForRpc). + LIBBINDER_EXPORTED bool isForRpc() const; + + // Writes the IPC/RPC header. + LIBBINDER_EXPORTED status_t writeInterfaceToken(const String16& interface); + LIBBINDER_EXPORTED status_t writeInterfaceToken(const char16_t* str, size_t len); + + // Parses the RPC header, returning true if the interface name + // in the header matches the expected interface from the caller. + // + // Additionally, enforceInterface does part of the work of + // propagating the StrictMode policy mask, populating the current + // IPCThreadState, which as an optimization may optionally be + // passed in. + LIBBINDER_EXPORTED bool enforceInterface(const String16& interface, + IPCThreadState* threadState = nullptr) const; + LIBBINDER_EXPORTED bool enforceInterface(const char16_t* interface, size_t len, + IPCThreadState* threadState = nullptr) const; + LIBBINDER_EXPORTED bool checkInterface(IBinder*) const; + + // Verify there are no bytes left to be read on the Parcel. + // Returns Status(EX_BAD_PARCELABLE) when the Parcel is not consumed. + LIBBINDER_EXPORTED binder::Status enforceNoDataAvail() const; + + // This Api is used by fuzzers to skip dataAvail checks. + LIBBINDER_EXPORTED void setEnforceNoDataAvail(bool enforceNoDataAvail); + + // When fuzzing, we want to remove certain ABI checks that cause significant + // lost coverage, and we also want to avoid logs that cost too much to write. + LIBBINDER_EXPORTED void setServiceFuzzing(); + LIBBINDER_EXPORTED bool isServiceFuzzing() const; + + LIBBINDER_EXPORTED void freeData(); + + LIBBINDER_EXPORTED size_t objectsCount() const; + + LIBBINDER_EXPORTED status_t errorCheck() const; + LIBBINDER_EXPORTED void setError(status_t err); + + LIBBINDER_EXPORTED status_t write(const void* data, size_t len); + LIBBINDER_EXPORTED void* writeInplace(size_t len); + LIBBINDER_EXPORTED status_t writeInt32(int32_t val); + LIBBINDER_EXPORTED status_t writeUint32(uint32_t val); + LIBBINDER_EXPORTED status_t writeInt64(int64_t val); + LIBBINDER_EXPORTED status_t writeUint64(uint64_t val); + LIBBINDER_EXPORTED status_t writeFloat(float val); + LIBBINDER_EXPORTED status_t writeDouble(double val); + LIBBINDER_EXPORTED status_t writeCString(const char* str) + __attribute__((deprecated("use AIDL, writeString* instead"))); + LIBBINDER_EXPORTED status_t writeString8(const String8& str); + LIBBINDER_EXPORTED status_t writeString8(const char* str, size_t len); + LIBBINDER_EXPORTED status_t writeString16(const String16& str); + LIBBINDER_EXPORTED status_t writeString16(const std::optional& str); + LIBBINDER_EXPORTED status_t writeString16(const std::unique_ptr& str) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeString16(const char16_t* str, size_t len); + LIBBINDER_EXPORTED status_t writeStrongBinder(const sp& val); + LIBBINDER_EXPORTED status_t writeInt32Array(size_t len, const int32_t* val); + LIBBINDER_EXPORTED status_t writeByteArray(size_t len, const uint8_t* val); + LIBBINDER_EXPORTED status_t writeBool(bool val); + LIBBINDER_EXPORTED status_t writeChar(char16_t val); + LIBBINDER_EXPORTED status_t writeByte(int8_t val); + + // Take a UTF8 encoded string, convert to UTF16, write it to the parcel. + LIBBINDER_EXPORTED status_t writeUtf8AsUtf16(const std::string& str); + LIBBINDER_EXPORTED status_t writeUtf8AsUtf16(const std::optional& str); + LIBBINDER_EXPORTED status_t writeUtf8AsUtf16(const std::unique_ptr& str) + __attribute__((deprecated("use std::optional version instead"))); + + LIBBINDER_EXPORTED status_t writeByteVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeByteVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeByteVector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeByteVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeByteVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeByteVector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeInt32Vector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeInt32Vector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeInt32Vector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeInt64Vector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeInt64Vector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeInt64Vector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeUint64Vector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeUint64Vector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeUint64Vector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeFloatVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeFloatVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeFloatVector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeDoubleVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeDoubleVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeDoubleVector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeBoolVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeBoolVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeBoolVector(const std::vector& val); + LIBBINDER_EXPORTED status_t writeCharVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t writeCharVector(const std::unique_ptr>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeCharVector(const std::vector& val); + LIBBINDER_EXPORTED status_t + writeString16Vector(const std::optional>>& val); + LIBBINDER_EXPORTED status_t + writeString16Vector(const std::unique_ptr>>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeString16Vector(const std::vector& val); + LIBBINDER_EXPORTED status_t + writeUtf8VectorAsUtf16Vector(const std::optional>>& val); + LIBBINDER_EXPORTED status_t writeUtf8VectorAsUtf16Vector( + const std::unique_ptr>>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeUtf8VectorAsUtf16Vector(const std::vector& val); + + LIBBINDER_EXPORTED status_t + writeStrongBinderVector(const std::optional>>& val); + LIBBINDER_EXPORTED status_t + writeStrongBinderVector(const std::unique_ptr>>& val) + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t writeStrongBinderVector(const std::vector>& val); + + // Write an IInterface or a vector of IInterface's + template , bool> = true> + status_t writeStrongBinder(const sp& val) { + return writeStrongBinder(T::asBinder(val)); + } + template , bool> = true> + status_t writeStrongBinderVector(const std::vector>& val) { + return writeData(val); + } + template , bool> = true> + status_t writeStrongBinderVector(const std::optional>>& val) { + return writeData(val); + } + + template + status_t writeFixedArray(const std::array& val) { + return writeData(val); + } + template + status_t writeFixedArray(const std::optional>& val) { + return writeData(val); + } + + // Write an Enum vector with underlying type int8_t. + // Does not use padding; each byte is contiguous. + template && std::is_same_v,int8_t>, bool> = 0> + status_t writeEnumVector(const std::vector& val) + { return writeData(val); } + template && std::is_same_v,int8_t>, bool> = 0> + status_t writeEnumVector(const std::optional>& val) + { return writeData(val); } + template && std::is_same_v,int8_t>, bool> = 0> + [[deprecated("use std::optional version instead")]] // + status_t writeEnumVector(const std::unique_ptr>& val) + { return writeData(val); } + // Write an Enum vector with underlying type != int8_t. + template && !std::is_same_v,int8_t>, bool> = 0> + status_t writeEnumVector(const std::vector& val) + { return writeData(val); } + template && !std::is_same_v,int8_t>, bool> = 0> + status_t writeEnumVector(const std::optional>& val) + { return writeData(val); } + template && !std::is_same_v,int8_t>, bool> = 0> + [[deprecated("use std::optional version instead")]] // + status_t writeEnumVector(const std::unique_ptr>& val) + { return writeData(val); } + + template + status_t writeParcelableVector(const std::optional>>& val) + { return writeData(val); } + template + [[deprecated("use std::optional version instead")]] // + status_t writeParcelableVector(const std::unique_ptr>>& val) + { return writeData(val); } + template + [[deprecated("use std::optional version instead")]] // + status_t writeParcelableVector(const std::shared_ptr>>& val) + { return writeData(val); } + template + status_t writeParcelableVector(const std::shared_ptr>>& val) + { return writeData(val); } + template + status_t writeParcelableVector(const std::vector& val) + { return writeData(val); } + + template + status_t writeNullableParcelable(const std::optional& parcelable) + { return writeData(parcelable); } + template + status_t writeNullableParcelable(const std::unique_ptr& parcelable) { + return writeData(parcelable); + } + + LIBBINDER_EXPORTED status_t writeParcelable(const Parcelable& parcelable); + + template + status_t write(const Flattenable& val); + + template + status_t write(const LightFlattenable& val); + + template + status_t writeVectorSize(const std::vector& val); + template + status_t writeVectorSize(const std::optional>& val); + template + status_t writeVectorSize(const std::unique_ptr>& val) __attribute__((deprecated("use std::optional version instead"))); + +#ifndef BINDER_DISABLE_NATIVE_HANDLE + // Place a native_handle into the parcel (the native_handle's file- + // descriptors are dup'ed, so it is safe to delete the native_handle + // when this function returns). + // Doesn't take ownership of the native_handle. + LIBBINDER_EXPORTED status_t writeNativeHandle(const native_handle* handle); +#endif + + // Place a file descriptor into the parcel. The given fd must remain + // valid for the lifetime of the parcel. + // The Parcel does not take ownership of the given fd unless you ask it to. + LIBBINDER_EXPORTED status_t writeFileDescriptor(int fd, bool takeOwnership = false); + + // Place a file descriptor into the parcel. A dup of the fd is made, which + // will be closed once the parcel is destroyed. + LIBBINDER_EXPORTED status_t writeDupFileDescriptor(int fd); + + // Place a Java "parcel file descriptor" into the parcel. The given fd must remain + // valid for the lifetime of the parcel. + // The Parcel does not take ownership of the given fd unless you ask it to. + LIBBINDER_EXPORTED status_t writeParcelFileDescriptor(int fd, bool takeOwnership = false); + + // Place a Java "parcel file descriptor" into the parcel. A dup of the fd is made, which will + // be closed once the parcel is destroyed. + LIBBINDER_EXPORTED status_t writeDupParcelFileDescriptor(int fd); + + // Place a file descriptor into the parcel. This will not affect the + // semantics of the smart file descriptor. A new descriptor will be + // created, and will be closed when the parcel is destroyed. + LIBBINDER_EXPORTED status_t writeUniqueFileDescriptor(const binder::unique_fd& fd); + + // Place a vector of file desciptors into the parcel. Each descriptor is + // dup'd as in writeDupFileDescriptor + LIBBINDER_EXPORTED status_t + writeUniqueFileDescriptorVector(const std::optional>& val); + LIBBINDER_EXPORTED status_t + writeUniqueFileDescriptorVector(const std::vector& val); + + // WARNING: deprecated and incompatible with AIDL. You should use Parcelable + // definitions outside of Parcel to represent shared memory, such as + // IMemory or with ParcelFileDescriptor. We should remove this, or move it to be + // external to Parcel, it's not a very encapsulated API. + // + // Writes a blob to the parcel. + // If the blob is small, then it is stored in-place, otherwise it is + // transferred by way of an anonymous shared memory region. Prefer sending + // immutable blobs if possible since they may be subsequently transferred between + // processes without further copying whereas mutable blobs always need to be copied. + // The caller should call release() on the blob after writing its contents. + LIBBINDER_EXPORTED status_t writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob); + + // Write an existing immutable blob file descriptor to the parcel. + // This allows the client to send the same blob to multiple processes + // as long as it keeps a dup of the blob file descriptor handy for later. + LIBBINDER_EXPORTED status_t writeDupImmutableBlobFileDescriptor(int fd); + + // Like Parcel.java's writeNoException(). Just writes a zero int32. + // Currently the native implementation doesn't do any of the StrictMode + // stack gathering and serialization that the Java implementation does. + LIBBINDER_EXPORTED status_t writeNoException(); + + LIBBINDER_EXPORTED status_t read(void* outData, size_t len) const; + LIBBINDER_EXPORTED const void* readInplace(size_t len) const; + LIBBINDER_EXPORTED int32_t readInt32() const; + LIBBINDER_EXPORTED status_t readInt32(int32_t* pArg) const; + LIBBINDER_EXPORTED uint32_t readUint32() const; + LIBBINDER_EXPORTED status_t readUint32(uint32_t* pArg) const; + LIBBINDER_EXPORTED int64_t readInt64() const; + LIBBINDER_EXPORTED status_t readInt64(int64_t* pArg) const; + LIBBINDER_EXPORTED uint64_t readUint64() const; + LIBBINDER_EXPORTED status_t readUint64(uint64_t* pArg) const; + LIBBINDER_EXPORTED float readFloat() const; + LIBBINDER_EXPORTED status_t readFloat(float* pArg) const; + LIBBINDER_EXPORTED double readDouble() const; + LIBBINDER_EXPORTED status_t readDouble(double* pArg) const; + LIBBINDER_EXPORTED bool readBool() const; + LIBBINDER_EXPORTED status_t readBool(bool* pArg) const; + LIBBINDER_EXPORTED char16_t readChar() const; + LIBBINDER_EXPORTED status_t readChar(char16_t* pArg) const; + LIBBINDER_EXPORTED int8_t readByte() const; + LIBBINDER_EXPORTED status_t readByte(int8_t* pArg) const; + + // Read a UTF16 encoded string, convert to UTF8 + LIBBINDER_EXPORTED status_t readUtf8FromUtf16(std::string* str) const; + LIBBINDER_EXPORTED status_t readUtf8FromUtf16(std::optional* str) const; + LIBBINDER_EXPORTED status_t readUtf8FromUtf16(std::unique_ptr* str) const + __attribute__((deprecated("use std::optional version instead"))); + + LIBBINDER_EXPORTED const char* readCString() const + __attribute__((deprecated("use AIDL, use readString*"))); + LIBBINDER_EXPORTED String8 readString8() const; + LIBBINDER_EXPORTED status_t readString8(String8* pArg) const; + LIBBINDER_EXPORTED const char* readString8Inplace(size_t* outLen) const; + LIBBINDER_EXPORTED String16 readString16() const; + LIBBINDER_EXPORTED status_t readString16(String16* pArg) const; + LIBBINDER_EXPORTED status_t readString16(std::optional* pArg) const; + LIBBINDER_EXPORTED status_t readString16(std::unique_ptr* pArg) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED const char16_t* readString16Inplace(size_t* outLen) const; + LIBBINDER_EXPORTED sp readStrongBinder() const; + LIBBINDER_EXPORTED status_t readStrongBinder(sp* val) const; + LIBBINDER_EXPORTED status_t readNullableStrongBinder(sp* val) const; + + // Read an Enum vector with underlying type int8_t. + // Does not use padding; each byte is contiguous. + template && std::is_same_v,int8_t>, bool> = 0> + status_t readEnumVector(std::vector* val) const + { return readData(val); } + template && std::is_same_v,int8_t>, bool> = 0> + [[deprecated("use std::optional version instead")]] // + status_t readEnumVector(std::unique_ptr>* val) const + { return readData(val); } + template && std::is_same_v,int8_t>, bool> = 0> + status_t readEnumVector(std::optional>* val) const + { return readData(val); } + // Read an Enum vector with underlying type != int8_t. + template && !std::is_same_v,int8_t>, bool> = 0> + status_t readEnumVector(std::vector* val) const + { return readData(val); } + template && !std::is_same_v,int8_t>, bool> = 0> + [[deprecated("use std::optional version instead")]] // + status_t readEnumVector(std::unique_ptr>* val) const + { return readData(val); } + template && !std::is_same_v,int8_t>, bool> = 0> + status_t readEnumVector(std::optional>* val) const + { return readData(val); } + + template + status_t readParcelableVector( + std::optional>>* val) const + { return readData(val); } + template + [[deprecated("use std::optional version instead")]] // + status_t readParcelableVector( + std::unique_ptr>>* val) const + { return readData(val); } + template + status_t readParcelableVector(std::vector* val) const + { return readData(val); } + + LIBBINDER_EXPORTED status_t readParcelable(Parcelable* parcelable) const; + + template + status_t readParcelable(std::optional* parcelable) const + { return readData(parcelable); } + template + status_t readParcelable(std::unique_ptr* parcelable) const { + return readData(parcelable); + } + + // If strong binder would be nullptr, readStrongBinder() returns an error. + // TODO: T must be derived from IInterface, fix for clarity. + template + status_t readStrongBinder(sp* val) const; + + template + status_t readNullableStrongBinder(sp* val) const; + + LIBBINDER_EXPORTED status_t + readStrongBinderVector(std::optional>>* val) const; + LIBBINDER_EXPORTED status_t + readStrongBinderVector(std::unique_ptr>>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readStrongBinderVector(std::vector>* val) const; + template , bool> = true> + status_t readStrongBinderVector(std::vector>* val) const { + return readData(val); + } + template , bool> = true> + status_t readStrongBinderVector(std::optional>>* val) const { + return readData(val); + } + + LIBBINDER_EXPORTED status_t readByteVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readByteVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readByteVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readByteVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readByteVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readByteVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readInt32Vector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readInt32Vector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readInt32Vector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readInt64Vector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readInt64Vector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readInt64Vector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readUint64Vector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readUint64Vector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readUint64Vector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readFloatVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readFloatVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readFloatVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readDoubleVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readDoubleVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readDoubleVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readBoolVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readBoolVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readBoolVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readCharVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t readCharVector(std::unique_ptr>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readCharVector(std::vector* val) const; + LIBBINDER_EXPORTED status_t + readString16Vector(std::optional>>* val) const; + LIBBINDER_EXPORTED status_t + readString16Vector(std::unique_ptr>>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readString16Vector(std::vector* val) const; + LIBBINDER_EXPORTED status_t readUtf8VectorFromUtf16Vector( + std::optional>>* val) const; + LIBBINDER_EXPORTED status_t readUtf8VectorFromUtf16Vector( + std::unique_ptr>>* val) const + __attribute__((deprecated("use std::optional version instead"))); + LIBBINDER_EXPORTED status_t readUtf8VectorFromUtf16Vector(std::vector* val) const; + + template + status_t readFixedArray(std::array* val) const { + return readData(val); + } + template + status_t readFixedArray(std::optional>* val) const { + return readData(val); + } + + template + status_t read(Flattenable& val) const; + + template + status_t read(LightFlattenable& val) const; + + // resizeOutVector is used to resize AIDL out vector parameters. + template + status_t resizeOutVector(std::vector* val) const; + template + status_t resizeOutVector(std::optional>* val) const; + template + status_t resizeOutVector(std::unique_ptr>* val) const __attribute__((deprecated("use std::optional version instead"))); + + // Like Parcel.java's readExceptionCode(). Reads the first int32 + // off of a Parcel's header, returning 0 or the negative error + // code on exceptions, but also deals with skipping over rich + // response headers. Callers should use this to read & parse the + // response headers rather than doing it by hand. + LIBBINDER_EXPORTED int32_t readExceptionCode() const; + +#ifndef BINDER_DISABLE_NATIVE_HANDLE + // Retrieve native_handle from the parcel. This returns a copy of the + // parcel's native_handle (the caller takes ownership). The caller + // must free the native_handle with native_handle_close() and + // native_handle_delete(). + LIBBINDER_EXPORTED native_handle* readNativeHandle() const; +#endif + + // Retrieve a file descriptor from the parcel. This returns the raw fd + // in the parcel, which you do not own -- use dup() to get your own copy. + LIBBINDER_EXPORTED int readFileDescriptor() const; + + // Retrieve a Java "parcel file descriptor" from the parcel. This returns the raw fd + // in the parcel, which you do not own -- use dup() to get your own copy. + LIBBINDER_EXPORTED int readParcelFileDescriptor() const; + + // Retrieve a smart file descriptor from the parcel. + LIBBINDER_EXPORTED status_t readUniqueFileDescriptor(binder::unique_fd* val) const; + + // Retrieve a Java "parcel file descriptor" from the parcel. + LIBBINDER_EXPORTED status_t readUniqueParcelFileDescriptor(binder::unique_fd* val) const; + + // Retrieve a vector of smart file descriptors from the parcel. + LIBBINDER_EXPORTED status_t + readUniqueFileDescriptorVector(std::optional>* val) const; + LIBBINDER_EXPORTED status_t + readUniqueFileDescriptorVector(std::vector* val) const; + + // WARNING: deprecated and incompatible with AIDL. You should use Parcelable + // definitions outside of Parcel to represent shared memory, such as + // IMemory or with ParcelFileDescriptor. We should remove this, or move it to be + // external to Parcel, it's not a very encapsulated API. + // + // Reads a blob from the parcel. + // The caller should call release() on the blob after reading its contents. + LIBBINDER_EXPORTED status_t readBlob(size_t len, ReadableBlob* outBlob) const; + + LIBBINDER_EXPORTED const flat_binder_object* readObject(bool nullMetaData) const; + + // Debugging: get metrics on current allocations. + LIBBINDER_EXPORTED static size_t getGlobalAllocSize(); + LIBBINDER_EXPORTED static size_t getGlobalAllocCount(); + + LIBBINDER_EXPORTED bool replaceCallingWorkSourceUid(uid_t uid); + // Returns the work source provided by the caller. This can only be trusted for trusted calling + // uid. + LIBBINDER_EXPORTED uid_t readCallingWorkSourceUid() const; + + LIBBINDER_EXPORTED void print(std::ostream& to, uint32_t flags = 0) const; + + // This API is to quickly become a view of another Parcel, so that we can also + // test 'owner' paths quickly. It's extremely dangerous to use this API in + // practice, and you should never ever do it. + LIBBINDER_EXPORTED void makeDangerousViewOf(Parcel* p); + +private: + // Close all file descriptors in the parcel at object positions >= newObjectsSize. + void closeFileDescriptors(size_t newObjectsSize); + + // `objects` and `objectsSize` always 0 for RPC Parcels. + typedef void (*release_func)(const uint8_t* data, size_t dataSize, const binder_size_t* objects, + size_t objectsSize); + + uintptr_t ipcData() const; + size_t ipcDataSize() const; + uintptr_t ipcObjects() const; + size_t ipcObjectsCount() const; + void ipcSetDataReference(const uint8_t* data, size_t dataSize, const binder_size_t* objects, + size_t objectsCount, release_func relFunc); + // Takes ownership even when an error is returned. + [[nodiscard]] status_t rpcSetDataReference( + const sp& session, const uint8_t* data, size_t dataSize, + const uint32_t* objectTable, size_t objectTableSize, + std::vector>&& ancillaryFds, + release_func relFunc); + + status_t finishWrite(size_t len); + void releaseObjects(); + void reacquireObjects(size_t objectSize); + status_t growData(size_t len); + // Clear the Parcel and set the capacity to `desired`. + // Doesn't reset the RPC session association. + status_t restartWrite(size_t desired); + // Set the capacity to `desired`, truncating the Parcel if necessary. + status_t continueWrite(size_t desired); + status_t truncateRpcObjects(size_t newObjectsSize); + status_t writeObject(const flat_binder_object& val, bool nullMetaData); + status_t writePointer(uintptr_t val); + status_t readPointer(uintptr_t *pArg) const; + uintptr_t readPointer() const; + void freeDataNoInit(); + void initState(); + void scanForFds() const; + status_t scanForBinders(bool* result) const; + + status_t validateReadData(size_t len) const; + + void updateWorkSourceRequestHeaderPosition() const; + + status_t finishFlattenBinder(const sp& binder); + status_t finishUnflattenBinder(const sp& binder, sp* out) const; + status_t flattenBinder(const sp& binder); + status_t unflattenBinder(sp* out) const; + + LIBBINDER_EXPORTED status_t readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const; + + template + status_t readAligned(T *pArg) const; + + template T readAligned() const; + + template + status_t writeAligned(T val); + + status_t writeRawNullableParcelable(const Parcelable* + parcelable); + + //----------------------------------------------------------------------------- + // Generic type read and write methods for Parcel: + // + // readData(T *value) will read a value from the Parcel. + // writeData(const T& value) will write a value to the Parcel. + // + // Our approach to parceling is based on two overloaded functions + // readData() and writeData() that generate parceling code for an + // object automatically based on its type. The code from templates are generated at + // compile time (if constexpr), and decomposes an object through a call graph matching + // recursive descent of the template typename. + // + // This approach unifies handling of complex objects, + // resulting in fewer lines of code, greater consistency, + // extensibility to nested types, efficiency (decisions made at compile time), + // and better code maintainability and optimization. + // + // Design decision: Incorporate the read and write code into Parcel rather than + // as a non-intrusive serializer that emits a byte stream, as we have + // active objects, alignment, legacy code, and historical idiosyncrasies. + // + // --- Overview + // + // Parceling is a way of serializing objects into a sequence of bytes for communication + // between processes, as part of marshaling data for remote procedure calls. + // + // The Parcel instance contains objects serialized as bytes, such as the following: + // + // 1) Ordinary primitive data such as int, float. + // 2) Established structured data such as String16, std::string. + // 3) Parcelables, which are C++ objects that derive from Parcelable (and thus have a + // readFromParcel and writeToParcel method). (Similar for Java) + // 4) A std::vector<> of such data. + // 5) Nullable objects contained in std::optional, std::unique_ptr, or std::shared_ptr. + // + // And active objects from the Android ecosystem such as: + // 6) File descriptors, unique_fd (kernel object handles) + // 7) Binder objects, sp (active Android RPC handles) + // + // Objects from (1) through (5) serialize into the mData buffer. + // Active objects (6) and (7) serialize into both mData and mObjects buffers. + // + // --- Data layout details + // + // Data is read or written to the parcel by recursively decomposing the type of the parameter + // type T through readData() and writeData() methods. + // + // We focus on writeData() here in our explanation of the data layout. + // + // 1) Alignment + // Implementation detail: Regardless of the parameter type, writeData() calls are designed + // to finish at a multiple of 4 bytes, the default alignment of the Parcel. + // + // Writes of single uint8_t, int8_t, enums based on types of size 1, char16_t, etc + // will result in 4 bytes being written. The data is widened to int32 and then written; + // hence the position of the nonzero bytes depend on the native endianness of the CPU. + // + // Writes of primitive values with 8 byte size, double, int64_t, uint64_t, + // are stored with 4 byte alignment. The ARM and x86/x64 permit unaligned reads + // and writes (albeit with potential latency/throughput penalty) which may or may + // not be observable unless the process is IO bound. + // + // 2) Parcelables + // Parcelables are detected by the type's base class, and implemented through calling + // into the Parcelable type's readFromParcel() or writeToParcel() methods. + // Historically, due to null object detection, a (int32_t) 1 is prepended to the data written. + // Parcelables must have a default constructor (i.e. one that takes no arguments). + // + // 3) Arrays + // Arrays of uint8_t and int8_t, and enums based on size 1 are written as + // a contiguous packed byte stream. Hidden zero padding is applied at the end of the byte + // stream to make a multiple of 4 bytes (and prevent info leakage when writing). + // + // All other array writes can be conceptually thought of as recursively calling + // writeData on the individual elements (though may be implemented differently for speed). + // As discussed in (1), alignment rules are therefore applied for each element + // write (not as an aggregate whole), so the wire representation of data can be + // substantially larger. + // + // Historical Note: + // Because of element-wise alignment, CharVector and BoolVector are expanded + // element-wise into integers even though they could have been optimized to be packed + // just like uint8_t, int8_t (size 1 data). + // + // 3.1) Arrays accessed by the std::vector type. This is the default for AIDL. + // + // 4) Nullables + // std::optional, std::unique_ptr, std::shared_ptr are all parceled identically + // (i.e. result in identical byte layout). + // The target of the std::optional, std::unique_ptr, or std::shared_ptr + // can either be a std::vector, String16, std::string, or a Parcelable. + // + // Detection of null relies on peeking the first int32 data and checking if the + // the peeked value is considered invalid for the object: + // (-1 for vectors, String16, std::string) (0 for Parcelables). If the peeked value + // is invalid, then a null is returned. + // + // Application Note: When to use each nullable type: + // + // std::optional: Embeds the object T by value rather than creating a new instance + // by managed pointer as std::unique_ptr or std::shared_ptr. This will save a malloc + // when creating an optional instance. + // + // Use of std::optionals by value can result in copies of the underlying value stored in it, + // so a std::move may be used to move in and move out (for example) a vector value into + // the std::optional or for the std::optional itself. + // + // std::unique_ptr, std::shared_ptr: These are preferred when the lifetime of the object is + // already managed by the application. This reduces unnecessary copying of data + // especially when the calls are local in-proc (rather than via binder rpc). + // + // 5) StrongBinder (sp) + // StrongBinder objects are written regardless of null. When read, null StrongBinder values + // will be interpreted as UNKNOWN_ERROR if the type is a single argument > + // or in a vector argument >. However, they will be read without an error + // if present in a std::optional, std::unique_ptr, or std::shared_ptr vector, e.g. + // >>. + // + // See AIDL annotation @Nullable, readStrongBinder(), and readNullableStrongBinder(). + // + // Historical Note: writing a vector of StrongBinder objects > + // containing a null will not cause an error. However reading such a vector will cause + // an error _and_ early termination of the read. + + // --- Examples + // + // Using recursive parceling, we can parcel complex data types so long + // as they obey the rules described above. + // + // Example #1 + // Parceling of a 3D vector + // + // std::vector>> v1 { + // { {1}, {2, 3}, {4} }, + // {}, + // { {10}, {20}, {30, 40} }, + // }; + // Parcel p1; + // p1.writeData(v1); + // decltype(v1) v2; + // p1.setDataPosition(0); + // p1.readData(&v2); + // ASSERT_EQ(v1, v2); + // + // Example #2 + // Parceling of mixed shared pointers + // + // Parcel p1; + // auto sp1 = std::make_shared>>>(3); + // (*sp1)[2] = std::make_shared>(3); + // (*(*sp1)[2])[2] = 2; + // p1.writeData(sp1); + // decltype(sp1) sp2; + // p1.setDataPosition(0); + // p1.readData(&sp2); + // ASSERT_EQ((*sp1)[0], (*sp2)[0]); // nullptr + // ASSERT_EQ((*sp1)[1], (*sp2)[1]); // nullptr + // ASSERT_EQ(*(*sp1)[2], *(*sp2)[2]); // { 0, 0, 2} + + // --- Helper Methods + // TODO: move this to a utils header. + // + // Determine if a type is a specialization of a templated type + // Example: is_specialization_v + + template class Ref> + struct is_specialization : std::false_type {}; + + template