Merge "Improve Rust documentation of Binder thread pool."
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index e84428e..c6132e8 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2374,11 +2374,15 @@
         p->fts_number = p->fts_parent->fts_number;
         switch (p->fts_info) {
         case FTS_D:
-            if (p->fts_level == 4
+            if (p->fts_level == 3
+                    && !strcmp(p->fts_parent->fts_name, "obb")
+                    && !strcmp(p->fts_parent->fts_parent->fts_name, "Android")) {
+                p->fts_number = 1;
+            } else if (p->fts_level == 4
                     && !strcmp(p->fts_name, "cache")
                     && !strcmp(p->fts_parent->fts_parent->fts_name, "data")
                     && !strcmp(p->fts_parent->fts_parent->fts_parent->fts_name, "Android")) {
-                p->fts_number = 1;
+                p->fts_number = 2;
             }
             [[fallthrough]]; // to count the directory
         case FTS_DEFAULT:
@@ -2387,9 +2391,13 @@
         case FTS_SLNONE:
             int64_t size = (p->fts_statp->st_blocks * 512);
             if (p->fts_number == 1) {
-                stats->cacheSize += size;
+                stats->codeSize += size;
+            } else {
+                if (p->fts_number == 2) {
+                    stats->cacheSize += size;
+                }
+                stats->dataSize += size;
             }
-            stats->dataSize += size;
             break;
         }
     }
@@ -2735,11 +2743,6 @@
         extStats.dataSize = dataSize;
         atrace_pm_end();
     } else {
-        atrace_pm_begin("obb");
-        auto obbPath = create_data_path(uuid_) + "/media/obb";
-        calculate_tree_size(obbPath, &extStats.codeSize);
-        atrace_pm_end();
-
         atrace_pm_begin("code");
         calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
         atrace_pm_end();
@@ -2770,9 +2773,10 @@
         atrace_pm_begin("external");
         auto dataMediaPath = create_data_media_path(uuid_, userId);
         collectManualExternalStatsForUser(dataMediaPath, &extStats);
+
 #if MEASURE_DEBUG
         LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache "
-                << extStats.cacheSize;
+                << extStats.cacheSize << " code " << extStats.codeSize;
 #endif
         atrace_pm_end();
 
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index 9949de2..6273804 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -138,6 +138,8 @@
 
     /**
      * Dumps information about the interface. By default, dumps nothing.
+     *
+     * This method is not given ownership of the FD.
      */
     virtual inline binder_status_t dump(int fd, const char** args, uint32_t numArgs);
 
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index 24a9345..45c3a90 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -33,6 +33,10 @@
             .extraFds = {},
     };
 
+    // always refresh the calling identity, because we sometimes set it below, but also,
+    // the code we're fuzzing might reset it
+    IPCThreadState::self()->clearCallingIdentity();
+
     // Always take so that a perturbation of just the one ConsumeBool byte will always
     // take the same path, but with a different UID. Without this, the fuzzer needs to
     // guess both the change in value and the shift at the same time.
@@ -43,72 +47,45 @@
     }
 
     while (provider.remaining_bytes() > 0) {
-        provider.PickValueInArray<std::function<void()>>({
-                [&]() {
-                    // Most of the AIDL services will have small set of transaction codes.
-                    uint32_t code = provider.ConsumeBool()
-                            ? provider.ConsumeIntegral<uint32_t>()
-                            : provider.ConsumeIntegralInRange<uint32_t>(0, 100);
-                    uint32_t flags = provider.ConsumeIntegral<uint32_t>();
-                    Parcel data;
-                    // for increased fuzz coverage
-                    data.setEnforceNoDataAvail(false);
-                    data.setServiceFuzzing();
+        // Most of the AIDL services will have small set of transaction codes.
+        uint32_t code = provider.ConsumeBool() ? provider.ConsumeIntegral<uint32_t>()
+                                               : provider.ConsumeIntegralInRange<uint32_t>(0, 100);
+        uint32_t flags = provider.ConsumeIntegral<uint32_t>();
+        Parcel data;
+        // for increased fuzz coverage
+        data.setEnforceNoDataAvail(false);
+        data.setServiceFuzzing();
 
-                    sp<IBinder> target = options.extraBinders.at(
-                            provider.ConsumeIntegralInRange<size_t>(0,
-                                                                    options.extraBinders.size() -
-                                                                            1));
-                    options.writeHeader = [&target](Parcel* p, FuzzedDataProvider& provider) {
-                        // most code will be behind checks that the head of the Parcel
-                        // is exactly this, so make it easier for fuzzers to reach this
-                        if (provider.ConsumeBool()) {
-                            p->writeInterfaceToken(target->getInterfaceDescriptor());
-                        }
-                    };
+        sp<IBinder> target = options.extraBinders.at(
+                provider.ConsumeIntegralInRange<size_t>(0, options.extraBinders.size() - 1));
+        options.writeHeader = [&target](Parcel* p, FuzzedDataProvider& provider) {
+            // most code will be behind checks that the head of the Parcel
+            // is exactly this, so make it easier for fuzzers to reach this
+            if (provider.ConsumeBool()) {
+                p->writeInterfaceToken(target->getInterfaceDescriptor());
+            }
+        };
 
-                    std::vector<uint8_t> subData = provider.ConsumeBytes<uint8_t>(
-                            provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes()));
-                    fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()),
-                                     &options);
+        std::vector<uint8_t> subData = provider.ConsumeBytes<uint8_t>(
+                provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes()));
+        fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), &options);
 
-                    Parcel reply;
-                    // for increased fuzz coverage
-                    reply.setEnforceNoDataAvail(false);
-                    reply.setServiceFuzzing();
-                    (void)target->transact(code, data, &reply, flags);
+        Parcel reply;
+        // for increased fuzz coverage
+        reply.setEnforceNoDataAvail(false);
+        reply.setServiceFuzzing();
+        (void)target->transact(code, data, &reply, flags);
 
-                    // feed back in binders and fds that are returned from the service, so that
-                    // we can fuzz those binders, and use the fds and binders to feed back into
-                    // the binders
-                    auto retBinders = reply.debugReadAllStrongBinders();
-                    options.extraBinders.insert(options.extraBinders.end(), retBinders.begin(),
-                                                retBinders.end());
-                    auto retFds = reply.debugReadAllFileDescriptors();
-                    for (size_t i = 0; i < retFds.size(); i++) {
-                        options.extraFds.push_back(base::unique_fd(dup(retFds[i])));
-                    }
-                },
-                [&]() {
-                    if (options.extraFds.size() == 0) {
-                        return;
-                    }
-                    uint32_t toDelete =
-                            provider.ConsumeIntegralInRange<uint32_t>(0,
-                                                                      options.extraFds.size() - 1);
-                    options.extraFds.erase(options.extraFds.begin() + toDelete);
-                },
-                [&]() {
-                    if (options.extraBinders.size() <= 1) {
-                        return;
-                    }
-                    uint32_t toDelete =
-                            provider.ConsumeIntegralInRange<uint32_t>(0,
-                                                                      options.extraBinders.size() -
-                                                                              1);
-                    options.extraBinders.erase(options.extraBinders.begin() + toDelete);
-                },
-        })();
+        // feed back in binders and fds that are returned from the service, so that
+        // we can fuzz those binders, and use the fds and binders to feed back into
+        // the binders
+        auto retBinders = reply.debugReadAllStrongBinders();
+        options.extraBinders.insert(options.extraBinders.end(), retBinders.begin(),
+                                    retBinders.end());
+        auto retFds = reply.debugReadAllFileDescriptors();
+        for (size_t i = 0; i < retFds.size(); i++) {
+            options.extraFds.push_back(base::unique_fd(dup(retFds[i])));
+        }
     }
 
     // invariants
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/ITestService.aidl b/libs/binder/tests/parcel_fuzzer/test_fuzzer/ITestService.aidl
index 3eadc02..5089ae5 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/ITestService.aidl
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/ITestService.aidl
@@ -21,4 +21,6 @@
     void setCharData(char input);
 
     void setBooleanData(boolean input);
-}
\ No newline at end of file
+
+    void setService(ITestService service);
+}
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
index 8907ea0..7fbf2d0 100644
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/TestServiceFuzzer.cpp
@@ -17,35 +17,102 @@
 #include <BnTestService.h>
 #include <fuzzbinder/libbinder_driver.h>
 
+#include <binder/IPCThreadState.h>
 #include <log/log.h>
 
-using android::fuzzService;
-using android::sp;
 using android::binder::Status;
 
 namespace android {
+
+enum class CrashType {
+    NONE,
+    ON_PLAIN,
+    ON_BINDER,
+    ON_KNOWN_UID,
+};
+
 // This service is to verify that fuzzService is functioning properly
 class TestService : public BnTestService {
 public:
-    Status setIntData(int /*input*/) {
-        LOG_ALWAYS_FATAL("Expected crash in setIntData");
+    TestService(CrashType crash) : mCrash(crash) {}
+
+    void onData() {
+        switch (mCrash) {
+            case CrashType::ON_PLAIN: {
+                LOG_ALWAYS_FATAL("Expected crash, PLAIN.");
+                break;
+            }
+            case CrashType::ON_KNOWN_UID: {
+                if (IPCThreadState::self()->getCallingUid() == getuid()) {
+                    LOG_ALWAYS_FATAL("Expected crash, KNOWN_UID.");
+                }
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    Status setIntData(int /*input*/) override {
+        onData();
         return Status::ok();
     }
 
-    Status setCharData(char16_t /*input*/) {
-        LOG_ALWAYS_FATAL("Expected crash in setCharData");
+    Status setCharData(char16_t /*input*/) override {
+        onData();
         return Status::ok();
     }
 
-    Status setBooleanData(bool /*input*/) {
-        LOG_ALWAYS_FATAL("Expected crash in setBooleanData");
+    Status setBooleanData(bool /*input*/) override {
+        onData();
         return Status::ok();
     }
+
+    Status setService(const sp<ITestService>& service) override {
+        onData();
+        if (mCrash == CrashType::ON_BINDER && service != nullptr) {
+            LOG_ALWAYS_FATAL("Expected crash, BINDER.");
+        }
+        return Status::ok();
+    }
+
+private:
+    CrashType mCrash;
 };
-} // namespace android
+
+CrashType gCrashType = CrashType::NONE;
+
+extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
+    if (*argc < 2) {
+        printf("You must specify at least one argument\n");
+        exit(0); // success because this is a crash test
+    }
+
+    std::string arg = std::string((*argv)[1]);
+
+    // ignore first argument, because we consume it
+    (*argv)[1] = (*argv[0]);
+    (*argc)--;
+    (*argv)++;
+
+    if (arg == "PLAIN") {
+        gCrashType = CrashType::ON_PLAIN;
+    } else if (arg == "KNOWN_UID") {
+        gCrashType = CrashType::ON_KNOWN_UID;
+    } else if (arg == "BINDER") {
+        gCrashType = CrashType::ON_BINDER;
+    } else {
+        printf("INVALID ARG\n");
+        exit(0); // success because this is a crash test
+    }
+
+    return 0;
+}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    auto service = sp<android::TestService>::make();
+    auto service = sp<TestService>::make(gCrashType);
     fuzzService(service, FuzzedDataProvider(data, size));
     return 0;
 }
+
+} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh b/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
old mode 100644
new mode 100755
index cec52fd..e568035
--- a/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
+++ b/libs/binder/tests/parcel_fuzzer/test_fuzzer/run_fuzz_service_test.sh
@@ -27,16 +27,18 @@
     exit 1
 fi
 
-echo "INFO: Running fuzzer : test_service_fuzzer_should_crash"
+for CRASH_TYPE in PLAIN KNOWN_UID BINDER; do
+    echo "INFO: Running fuzzer : test_service_fuzzer_should_crash $CRASH_TYPE"
 
-./test_service_fuzzer_should_crash -max_total_time=30 &>${FUZZER_OUT}
+    ./test_service_fuzzer_should_crash "$CRASH_TYPE" -max_total_time=30 &>"$FUZZER_OUT"
 
-echo "INFO: Searching fuzzer output for expected crashes"
-if grep -q "Expected crash in set" ${FUZZER_OUT};
-then
-    echo -e "${color_success}Success: Found expected crash. fuzzService test successful!"
-else
-    echo -e "${color_failed}Failed: Unable to find successful fuzzing output from test_service_fuzzer_should_crash"
-    echo "${color_reset}"
-    exit 1
-fi
+    echo "INFO: Searching fuzzer output for expected crashes"
+    if grep -q "Expected crash, $CRASH_TYPE." "$FUZZER_OUT"
+    then
+        echo -e "${color_success}Success: Found expected crash. fuzzService test successful!"
+    else
+        echo -e "${color_failed}Failed: Unable to find successful fuzzing output from test_service_fuzzer_should_crash"
+        echo "${color_reset}"
+        exit 1
+    fi
+done
diff --git a/services/gpuservice/OWNERS b/services/gpuservice/OWNERS
index 0ff65bf..07c681f 100644
--- a/services/gpuservice/OWNERS
+++ b/services/gpuservice/OWNERS
@@ -4,3 +4,4 @@
 lfy@google.com
 paulthomson@google.com
 pbaiget@google.com
+kocdemir@google.com