Binder file module

Test: mma
Bug: 302723053
Change-Id: Ie27f8a36ab56069c928079da8a0cf3d8bfb49813
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index f90c618..eccd5db 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -92,6 +92,7 @@
         "TextOutput.cpp",
         "Trace.cpp",
         "Utils.cpp",
+        "file.cpp",
     ],
 
     shared_libs: [
@@ -653,4 +654,7 @@
         "libutils",
         "android.debug_aidl-cpp",
     ],
+    static_libs: [
+        "libc++fs",
+    ],
 }
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 8102859..42dd691 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -27,8 +27,7 @@
 #include <stdio.h>
 
 #include "BuildFlags.h"
-
-#include <android-base/file.h>
+#include "file.h"
 
 //#undef ALOGV
 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
diff --git a/libs/binder/OS_unix_base.cpp b/libs/binder/OS_unix_base.cpp
index 28a0d5e..ca998d4 100644
--- a/libs/binder/OS_unix_base.cpp
+++ b/libs/binder/OS_unix_base.cpp
@@ -16,13 +16,15 @@
 
 #include "OS.h"
 #include "Utils.h"
+#include "file.h"
 
-#include <android-base/file.h>
 #include <binder/RpcTransportRaw.h>
 #include <log/log.h>
 #include <string.h>
 #include <sys/socket.h>
 
+using android::binder::ReadFully;
+
 namespace android::binder::os {
 
 // Linux kernel supports up to 253 (from SCM_MAX_FD) for unix sockets.
diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp
index eb3c543..525ba2e 100644
--- a/libs/binder/RecordedTransaction.cpp
+++ b/libs/binder/RecordedTransaction.cpp
@@ -14,19 +14,23 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
+#include "file.h"
+
 #include <binder/Functional.h>
 #include <binder/RecordedTransaction.h>
 #include <binder/unique_fd.h>
 
 #include <inttypes.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 #include <algorithm>
 
 using namespace android::binder::impl;
 using android::Parcel;
 using android::binder::borrowed_fd;
+using android::binder::ReadFully;
 using android::binder::unique_fd;
+using android::binder::WriteFully;
 using android::binder::debug::RecordedTransaction;
 
 #define PADDING8(s) ((8 - (s) % 8) % 8)
@@ -183,7 +187,7 @@
             return std::nullopt;
         }
 
-        if (!android::base::ReadFully(fd, &chunk, sizeof(ChunkDescriptor))) {
+        if (!ReadFully(fd, &chunk, sizeof(ChunkDescriptor))) {
             ALOGE("Failed to read ChunkDescriptor from fd %d. %s", fd.get(), strerror(errno));
             return std::nullopt;
         }
@@ -318,7 +322,7 @@
     buffer.insert(buffer.end(), checksumBytes, checksumBytes + sizeof(transaction_checksum_t));
 
     // Write buffer to file
-    if (!android::base::WriteFully(fd, buffer.data(), buffer.size())) {
+    if (!WriteFully(fd, buffer.data(), buffer.size())) {
         ALOGE("Failed to write chunk fd %d", fd.get());
         return UNKNOWN_ERROR;
     }
diff --git a/libs/binder/file.cpp b/libs/binder/file.cpp
new file mode 100644
index 0000000..bac667e
--- /dev/null
+++ b/libs/binder/file.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "file.h"
+
+#ifdef BINDER_NO_LIBBASE
+
+#include <stdint.h>
+
+// clang-format off
+
+namespace android::binder {
+
+bool ReadFully(borrowed_fd fd, void* data, size_t byte_count) {
+  uint8_t* p = reinterpret_cast<uint8_t*>(data);
+  size_t remaining = byte_count;
+  while (remaining > 0) {
+    ssize_t n = TEMP_FAILURE_RETRY(read(fd.get(), p, remaining));
+    if (n == 0) {  // EOF
+      errno = ENODATA;
+      return false;
+    }
+    if (n == -1) return false;
+    p += n;
+    remaining -= n;
+  }
+  return true;
+}
+
+bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count) {
+  const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
+  size_t remaining = byte_count;
+  while (remaining > 0) {
+    ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, remaining));
+    if (n == -1) return false;
+    p += n;
+    remaining -= n;
+  }
+  return true;
+}
+
+}  // namespace android::binder
+
+#endif // BINDER_NO_LIBBASE
diff --git a/libs/binder/file.h b/libs/binder/file.h
new file mode 100644
index 0000000..bcbfa31
--- /dev/null
+++ b/libs/binder/file.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifndef BINDER_NO_LIBBASE
+
+#include <android-base/file.h>
+
+namespace android::binder {
+using android::base::ReadFully;
+using android::base::WriteFully;
+} // namespace android::binder
+
+#else // BINDER_NO_LIBBASE
+
+#include <binder/unique_fd.h>
+
+#include <string_view>
+
+namespace android::binder {
+
+bool ReadFully(borrowed_fd fd, void* data, size_t byte_count);
+bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count);
+
+} // namespace android::binder
+
+#endif // BINDER_NO_LIBBASE
diff --git a/libs/binder/rust/tests/serialization.cpp b/libs/binder/rust/tests/serialization.cpp
index 08321e7..0cdf8c5 100644
--- a/libs/binder/rust/tests/serialization.cpp
+++ b/libs/binder/rust/tests/serialization.cpp
@@ -16,6 +16,7 @@
 
 #include "serialization.hpp"
 #include "../../FdUtils.h"
+#include "../../tests/FileUtils.h"
 
 #include <android/binder_ibinder_platform.h>
 #include <android/binder_libbinder.h>
@@ -27,7 +28,6 @@
 #include <gtest/gtest.h>
 #include <utils/Errors.h>
 #include <utils/String16.h>
-#include "android-base/file.h"
 
 #include <cmath>
 #include <cstdint>
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index f2693dd..18b178b 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -17,9 +17,9 @@
 #include <sysexits.h>
 #include <unistd.h>
 
+#include <filesystem>
 #include <iostream>
 
-#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android/debug/BnAdbCallback.h>
@@ -30,6 +30,8 @@
 #include <binder/ProcessState.h>
 #include <binder/RpcServer.h>
 
+#include "file.h"
+
 using android::BBinder;
 using android::defaultServiceManager;
 using android::OK;
@@ -38,7 +40,6 @@
 using android::status_t;
 using android::statusToString;
 using android::String16;
-using android::base::Basename;
 using android::base::GetBoolProperty;
 using android::base::InitLogging;
 using android::base::LogdLogger;
@@ -53,8 +54,8 @@
 using ServiceRetriever = decltype(&android::IServiceManager::checkService);
 using android::debug::IAdbManager;
 
-int Usage(const char* program) {
-    auto basename = Basename(program);
+int Usage(std::filesystem::path program) {
+    auto basename = program.filename();
     // clang-format off
     LOG(ERROR) << R"(dispatch calls to RPC service.
 Usage:
@@ -253,7 +254,8 @@
         mLogdLogger(id, severity, tag, file, line, message);
         if (severity >= LogSeverity::WARNING) {
             std::cout << std::flush;
-            std::cerr << Basename(getprogname()) << ": " << message << std::endl;
+            auto progname = std::filesystem::path(getprogname()).filename();
+            std::cerr << progname << ": " << message << std::endl;
         }
     }
 
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index cd3e7c0..ba8fb39 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -172,6 +172,30 @@
     ],
 }
 
+cc_library_static {
+    name: "libbinder_test_utils",
+    host_supported: true,
+    vendor_available: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    defaults: [
+        "binder_test_defaults",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+    srcs: [
+        "FileUtils.cpp",
+    ],
+    visibility: [
+        ":__subpackages__",
+    ],
+}
+
 cc_defaults {
     name: "binderRpcTest_common_defaults",
     host_supported: true,
@@ -185,6 +209,7 @@
     ],
 
     static_libs: [
+        "libbinder_test_utils",
         "libbinder_tls_static",
         "libbinder_tls_test_utils",
         "binderRpcTestIface-cpp",
diff --git a/libs/binder/tests/FileUtils.cpp b/libs/binder/tests/FileUtils.cpp
new file mode 100644
index 0000000..61509fe
--- /dev/null
+++ b/libs/binder/tests/FileUtils.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FileUtils.h"
+
+#ifdef BINDER_NO_LIBBASE
+
+#include <sys/stat.h>
+#include <filesystem>
+
+#if defined(__APPLE__)
+#include <mach-o/dyld.h>
+#endif
+#if defined(_WIN32)
+#include <direct.h>
+#include <windows.h>
+#endif
+
+namespace android::binder {
+
+bool ReadFdToString(borrowed_fd fd, std::string* content) {
+    content->clear();
+
+    // Although original we had small files in mind, this code gets used for
+    // very large files too, where the std::string growth heuristics might not
+    // be suitable. https://code.google.com/p/android/issues/detail?id=258500.
+    struct stat sb;
+    if (fstat(fd.get(), &sb) != -1 && sb.st_size > 0) {
+        content->reserve(sb.st_size);
+    }
+
+    char buf[4096] __attribute__((__uninitialized__));
+    ssize_t n;
+    while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) {
+        content->append(buf, n);
+    }
+    return (n == 0) ? true : false;
+}
+
+bool WriteStringToFd(std::string_view content, borrowed_fd fd) {
+    const char* p = content.data();
+    size_t left = content.size();
+    while (left > 0) {
+        ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, left));
+        if (n == -1) {
+            return false;
+        }
+        p += n;
+        left -= n;
+    }
+    return true;
+}
+
+static std::filesystem::path GetExecutablePath2() {
+#if defined(__linux__)
+    return std::filesystem::read_symlink("/proc/self/exe");
+#elif defined(__APPLE__)
+    char path[PATH_MAX + 1];
+    uint32_t path_len = sizeof(path);
+    int rc = _NSGetExecutablePath(path, &path_len);
+    if (rc < 0) {
+        std::unique_ptr<char> path_buf(new char[path_len]);
+        _NSGetExecutablePath(path_buf.get(), &path_len);
+        return path_buf.get();
+    }
+    return path;
+#elif defined(_WIN32)
+    char path[PATH_MAX + 1];
+    DWORD result = GetModuleFileName(NULL, path, sizeof(path) - 1);
+    if (result == 0 || result == sizeof(path) - 1) return "";
+    path[PATH_MAX - 1] = 0;
+    return path;
+#elif defined(__EMSCRIPTEN__)
+    abort();
+#else
+#error unknown OS
+#endif
+}
+
+std::string GetExecutableDirectory() {
+    return GetExecutablePath2().parent_path();
+}
+
+} // namespace android::binder
+
+#endif // BINDER_NO_LIBBASE
diff --git a/libs/binder/tests/FileUtils.h b/libs/binder/tests/FileUtils.h
new file mode 100644
index 0000000..2cbe5e7
--- /dev/null
+++ b/libs/binder/tests/FileUtils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 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 "../file.h"
+
+#ifndef BINDER_NO_LIBBASE
+
+namespace android::binder {
+using android::base::GetExecutableDirectory;
+using android::base::ReadFdToString;
+using android::base::WriteStringToFd;
+} // namespace android::binder
+
+#else // BINDER_NO_LIBBASE
+
+#include <binder/unique_fd.h>
+
+#include <string_view>
+
+#if !defined(_WIN32) && !defined(O_BINARY)
+/** Windows needs O_BINARY, but Unix never mangles line endings. */
+#define O_BINARY 0
+#endif
+
+namespace android::binder {
+
+bool ReadFdToString(borrowed_fd fd, std::string* content);
+bool WriteStringToFd(std::string_view content, borrowed_fd fd);
+
+std::string GetExecutableDirectory();
+
+} // namespace android::binder
+
+#endif // BINDER_NO_LIBBASE
diff --git a/libs/binder/tests/binderRecordReplayTest.cpp b/libs/binder/tests/binderRecordReplayTest.cpp
index ea89e38..73c0a94 100644
--- a/libs/binder/tests/binderRecordReplayTest.cpp
+++ b/libs/binder/tests/binderRecordReplayTest.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <BnBinderRecordReplayTest.h>
-#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
@@ -33,6 +32,7 @@
 
 #include <sys/prctl.h>
 
+#include "../file.h"
 #include "parcelables/SingleDataParcelable.h"
 
 using namespace android;
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 5d304f4..2769a88 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -43,6 +43,8 @@
 using namespace std::chrono_literals;
 using namespace std::placeholders;
 using android::binder::borrowed_fd;
+using android::binder::GetExecutableDirectory;
+using android::binder::ReadFdToString;
 using android::binder::unique_fd;
 using testing::AssertionFailure;
 using testing::AssertionResult;
@@ -260,7 +262,7 @@
     bool singleThreaded = GetParam().singleThreaded;
     bool noKernel = GetParam().noKernel;
 
-    std::string path = android::base::GetExecutableDirectory();
+    std::string path = GetExecutableDirectory();
     auto servicePath =
             std::format("{}/binder_rpc_test_service{}{}", path,
                         singleThreaded ? "_single_threaded" : "", noKernel ? "_no_kernel" : "");
@@ -591,12 +593,12 @@
     android::os::ParcelFileDescriptor fdA;
     EXPECT_OK(proc.rootIface->blockingRecvFd(&fdA));
     std::string result;
-    ASSERT_TRUE(android::base::ReadFdToString(fdA.get(), &result));
+    ASSERT_TRUE(ReadFdToString(fdA.get(), &result));
     EXPECT_EQ(result, "a");
 
     android::os::ParcelFileDescriptor fdB;
     EXPECT_OK(proc.rootIface->blockingRecvFd(&fdB));
-    ASSERT_TRUE(android::base::ReadFdToString(fdB.get(), &result));
+    ASSERT_TRUE(ReadFdToString(fdB.get(), &result));
     EXPECT_EQ(result, "b");
 
     saturateThreadPool(kNumServerThreads, proc.rootIface);
@@ -953,7 +955,7 @@
     ASSERT_TRUE(status.isOk()) << status;
 
     std::string result;
-    ASSERT_TRUE(android::base::ReadFdToString(out.get(), &result));
+    ASSERT_TRUE(ReadFdToString(out.get(), &result));
     ASSERT_EQ(result, "hello");
 }
 
@@ -983,7 +985,7 @@
     ASSERT_TRUE(status.isOk()) << status;
 
     std::string result;
-    EXPECT_TRUE(android::base::ReadFdToString(out.get(), &result));
+    EXPECT_TRUE(ReadFdToString(out.get(), &result));
     EXPECT_EQ(result, "123abcd");
 }
 
@@ -1008,7 +1010,7 @@
     ASSERT_TRUE(status.isOk()) << status;
 
     std::string result;
-    EXPECT_TRUE(android::base::ReadFdToString(out.get(), &result));
+    EXPECT_TRUE(ReadFdToString(out.get(), &result));
     EXPECT_EQ(result, std::string(253, 'a'));
 }
 
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index eeb26e0..a55edd2 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -41,7 +41,6 @@
 #endif
 
 #ifndef __TRUSTY__
-#include <android-base/file.h>
 #include <android/binder_auto_utils.h>
 #include <android/binder_libbinder.h>
 #include <binder/ProcessState.h>
@@ -60,6 +59,7 @@
 #include "../FdTrigger.h"
 #include "../FdUtils.h"
 #include "../RpcState.h" // for debugging
+#include "FileUtils.h"
 #include "format.h"
 #include "utils/Errors.h"
 
@@ -159,15 +159,15 @@
 #ifndef __TRUSTY__
 static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
     uint64_t length = str.length();
-    LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, &length, sizeof(length)));
-    LOG_ALWAYS_FATAL_IF(!android::base::WriteFully(fd, str.data(), str.length()));
+    LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
+    LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
 }
 
 static inline std::string readString(binder::borrowed_fd fd) {
     uint64_t length;
-    LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, &length, sizeof(length)));
+    LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
     std::string ret(length, '\0');
-    LOG_ALWAYS_FATAL_IF(!android::base::ReadFully(fd, ret.data(), length));
+    LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
     return ret;
 }
 
@@ -214,7 +214,7 @@
     LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
     RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
         signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
-        if (!WriteStringToFd(contents, writeFd)) {
+        if (!android::binder::WriteStringToFd(contents, writeFd)) {
             int savedErrno = errno;
             LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
                                 strerror(savedErrno));
diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp
index 5b7a5d2..28125f1 100644
--- a/libs/binder/tests/binderRpcTestService.cpp
+++ b/libs/binder/tests/binderRpcTestService.cpp
@@ -17,6 +17,7 @@
 #include "binderRpcTestCommon.h"
 
 using namespace android;
+using android::binder::ReadFdToString;
 using android::binder::unique_fd;
 
 class MyBinderRpcTestAndroid : public MyBinderRpcTestBase {
@@ -66,7 +67,7 @@
         std::string acc;
         for (const auto& file : files) {
             std::string result;
-            LOG_ALWAYS_FATAL_IF(!android::base::ReadFdToString(file.get(), &result));
+            LOG_ALWAYS_FATAL_IF(!ReadFdToString(file.get(), &result));
             acc.append(result);
         }
         out->reset(mockFileDescriptor(acc));
diff --git a/libs/binder/tests/binderTextOutputTest.cpp b/libs/binder/tests/binderTextOutputTest.cpp
index b37030e..a648c08 100644
--- a/libs/binder/tests/binderTextOutputTest.cpp
+++ b/libs/binder/tests/binderTextOutputTest.cpp
@@ -20,13 +20,14 @@
 #include <limits>
 #include <cstddef>
 
-#include "android-base/file.h"
 #include "android-base/test_utils.h"
 #include <gtest/gtest.h>
 
 #include <binder/Parcel.h>
 #include <binder/TextOutput.h>
 
+#include "../file.h"
+
 static void CheckMessage(CapturedStderr& cap,
                          const char* expected,
                          bool singleline) {
diff --git a/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp
index dabee7a..57521f4 100644
--- a/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
+#include "../../FileUtils.h"
+
 #include <android-base/logging.h>
 #include <binder/RecordedTransaction.h>
 #include <binder/unique_fd.h>
@@ -22,6 +23,7 @@
 #include <fuzzseeds/random_parcel_seeds.h>
 
 #include <sys/prctl.h>
+#include <sys/stat.h>
 
 using android::generateSeedsFromRecording;
 using android::status_t;
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h
index b3db035..694b68d 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel_seeds/fuzzseeds/random_parcel_seeds.h
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
+#include "../../../../file.h"
+
 #include <android-base/logging.h>
 
 #include <binder/Binder.h>
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
index f031137..7b3c806 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
 #include <android-base/logging.h>
 
 #include <binder/RecordedTransaction.h>
 
 #include <fuzzseeds/random_parcel_seeds.h>
 
-using android::base::WriteFully;
+#include "../../file.h"
+
 using android::binder::borrowed_fd;
+using android::binder::WriteFully;
 
 namespace android {
 namespace impl {
diff --git a/libs/binder/tests/rpc_fuzzer/Android.bp b/libs/binder/tests/rpc_fuzzer/Android.bp
index 71e847f..ab72bfd 100644
--- a/libs/binder/tests/rpc_fuzzer/Android.bp
+++ b/libs/binder/tests/rpc_fuzzer/Android.bp
@@ -25,13 +25,14 @@
         "libbase",
         "libcutils",
         "liblog",
+        "libbinder_test_utils",
         "libbinder_tls_static",
         "libbinder_tls_test_utils",
         "libssl_fuzz_unsafe",
         "libcrypto_fuzz_unsafe",
     ],
     cflags: [
-        "-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE" // for RAND_reset_for_fuzzing
+        "-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE", // for RAND_reset_for_fuzzing
     ],
     target: {
         android: {
diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp
index 1515732..50fc2f2 100644
--- a/libs/binder/tests/rpc_fuzzer/main.cpp
+++ b/libs/binder/tests/rpc_fuzzer/main.cpp
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
+#include "../FileUtils.h"
+
 #include <android-base/logging.h>
 #include <binder/Binder.h>
 #include <binder/Parcel.h>
@@ -29,9 +30,10 @@
 #include <openssl/ssl.h>
 
 #include <sys/resource.h>
+#include <sys/socket.h>
 #include <sys/un.h>
 
-using android::base::GetExecutableDirectory;
+using android::binder::GetExecutableDirectory;
 using android::binder::unique_fd;
 
 namespace android {
@@ -79,12 +81,12 @@
 ServerAuth readServerKeyAndCert() {
     ServerAuth ret;
 
-    auto keyPath = android::base::GetExecutableDirectory() + "/data/server.key";
+    auto keyPath = GetExecutableDirectory() + "/data/server.key";
     bssl::UniquePtr<BIO> keyBio(BIO_new_file(keyPath.c_str(), "r"));
     ret.pkey.reset(PEM_read_bio_PrivateKey(keyBio.get(), nullptr, passwordCallback, nullptr));
     CHECK_NE(ret.pkey.get(), nullptr);
 
-    auto certPath = android::base::GetExecutableDirectory() + "/data/server.crt";
+    auto certPath = GetExecutableDirectory() + "/data/server.crt";
     bssl::UniquePtr<BIO> certBio(BIO_new_file(certPath.c_str(), "r"));
     ret.cert.reset(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
     CHECK_NE(ret.cert.get(), nullptr);
diff --git a/libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp b/libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp
index 5e3502a..fe09978 100644
--- a/libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/TextOutputFuzz.cpp
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
+#include "../../file.h"
+
 #include <fuzzer/FuzzedDataProvider.h>
 
 #include <binder/Parcel.h>
 #include <binder/TextOutput.h>
-#include "android-base/file.h"
 #include "android-base/test_utils.h"
 
 #include <fcntl.h>
diff --git a/libs/binder/trusty/rules.mk b/libs/binder/trusty/rules.mk
index 9cad556..dbddbe1 100644
--- a/libs/binder/trusty/rules.mk
+++ b/libs/binder/trusty/rules.mk
@@ -43,6 +43,7 @@
 	$(LIBBINDER_DIR)/Stability.cpp \
 	$(LIBBINDER_DIR)/Status.cpp \
 	$(LIBBINDER_DIR)/Utils.cpp \
+	$(LIBBINDER_DIR)/file.cpp \
 	$(LIBBASE_DIR)/hex.cpp \
 	$(LIBBASE_DIR)/stringprintf.cpp \
 	$(LIBUTILS_DIR)/binder/Errors.cpp \