Merge "Snap for 6686656 from ea8305102a6cdd1b2cf89b1f020391bd19f71244 to sdk-release" into sdk-release
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 28fdaa4..fc3572c 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -239,6 +239,10 @@
         { OPT,      "events/kmem/ion_heap_shrink/enable" },
         { OPT,      "events/ion/ion_stat/enable" },
     } },
+    { "thermal",  "Thermal event", 0, {
+        { REQ,      "events/thermal/thermal_temperature/enable" },
+        { OPT,      "events/thermal/cdev_update/enable" },
+    } },
 };
 
 struct TracingVendorCategory {
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 9b2f4a8..28770f2 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -164,6 +164,12 @@
     chmod 0666 /sys/kernel/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
     chmod 0666 /sys/kernel/debug/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
 
+    # thermal
+    chmod 0666 /sys/kernel/debug/tracing/events/thermal/thermal_temperature/enable
+    chmod 0666 /sys/kernel/tracing/events/thermal/thermal_temperature/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/thermal/cdev_update/enable
+    chmod 0666 /sys/kernel/tracing/events/thermal/cdev_update/enable
+
 # Tracing disabled by default
     write /sys/kernel/debug/tracing/tracing_on 0
     write /sys/kernel/tracing/tracing_on 0
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 5afae4b..987adaf 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -75,7 +75,7 @@
     defaults: ["lshal_defaults"],
     gtest: true,
     static_libs: [
-        "android.hardware.tests.baz@1.0",
+        "android.hardware.tests.inheritance@1.0",
         "libgmock",
     ],
     shared_libs: [
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index af22ac9..72958bd 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -39,7 +39,7 @@
     // Optargs cannnot be used because the flag should not be considered set
     // if it should really be contained in mOptions.
     if (std::string(arg.argv[optind]) == "-E") {
-        mExcludesParentInstances = true;
+        mParentDebugInfoLevel = ParentDebugInfoLevel::NOTHING;
         optind++;
     }
 
@@ -67,7 +67,7 @@
 
     return mLshal.emitDebugInfo(
             pair.first, pair.second.empty() ? "default" : pair.second, mOptions,
-            mExcludesParentInstances,
+            mParentDebugInfoLevel,
             mLshal.out().buf(),
             mLshal.err());
 }
diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h
index cd57e31..317cc28 100644
--- a/cmds/lshal/DebugCommand.h
+++ b/cmds/lshal/DebugCommand.h
@@ -21,6 +21,7 @@
 #include <android-base/macros.h>
 
 #include "Command.h"
+#include "ParentDebugInfoLevel.h"
 #include "utils.h"
 
 namespace android {
@@ -42,9 +43,8 @@
     std::string mInterfaceName;
     std::vector<std::string> mOptions;
 
-    // Outputs the actual descriptor of a hal instead of the debug output
-    // if the arguments provided are a superclass of the actual hal impl.
-    bool mExcludesParentInstances;
+    // See comment on ParentDebugInfoLevel.
+    ParentDebugInfoLevel mParentDebugInfoLevel = ParentDebugInfoLevel::FULL;
 
     DISALLOW_COPY_AND_ASSIGN(DebugCommand);
 };
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index fb11cee..a805a48 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -555,7 +555,7 @@
                 std::stringstream ss;
                 auto pair = splitFirst(iName, '/');
                 mLshal.emitDebugInfo(pair.first, pair.second, {},
-                                     false /* excludesParentInstances */, ss,
+                                     ParentDebugInfoLevel::FQNAME_ONLY, ss,
                                      NullableOStream<std::ostream>(nullptr));
                 return ss.str();
             };
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 132b31e..2c3efe5 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -101,7 +101,7 @@
         const std::string &interfaceName,
         const std::string &instanceName,
         const std::vector<std::string> &options,
-        bool excludesParentInstances,
+        ParentDebugInfoLevel parentDebugInfoLevel,
         std::ostream &out,
         NullableOStream<std::ostream> err) const {
     using android::hidl::base::V1_0::IBase;
@@ -126,7 +126,7 @@
         return NO_INTERFACE;
     }
 
-    if (excludesParentInstances) {
+    if (parentDebugInfoLevel != ParentDebugInfoLevel::FULL) {
         const std::string descriptor = getDescriptor(base.get());
         if (descriptor.empty()) {
             std::string msg = interfaceName + "/" + instanceName + " getDescriptor failed";
@@ -134,6 +134,9 @@
             LOG(ERROR) << msg;
         }
         if (descriptor != interfaceName) {
+            if (parentDebugInfoLevel == ParentDebugInfoLevel::FQNAME_ONLY) {
+                out << "[See " << descriptor << "/" << instanceName << "]";
+            }
             return OK;
         }
     }
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index 830bd87..50279d4 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -25,6 +25,7 @@
 
 #include "Command.h"
 #include "NullableOStream.h"
+#include "ParentDebugInfoLevel.h"
 #include "utils.h"
 
 namespace android {
@@ -49,7 +50,7 @@
             const std::string &interfaceName,
             const std::string &instanceName,
             const std::vector<std::string> &options,
-            bool excludesParentInstances,
+            ParentDebugInfoLevel parentDebugInfoLevel,
             std::ostream &out,
             NullableOStream<std::ostream> err) const;
 
diff --git a/cmds/lshal/ParentDebugInfoLevel.h b/cmds/lshal/ParentDebugInfoLevel.h
new file mode 100644
index 0000000..12ac9c8
--- /dev/null
+++ b/cmds/lshal/ParentDebugInfoLevel.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+namespace android {
+namespace lshal {
+
+// Describe verbosity when dumping debug information on a HAL service by
+// referring to a parent HAL interface FQName (for example, when dumping debug information
+// on foo@1.0::IFoo but the HAL implementation is foo@1.1::IFoo).
+enum class ParentDebugInfoLevel {
+    // Write nothing.
+    NOTHING,
+    // Write a short description that includes the FQName of the real implementation.
+    FQNAME_ONLY,
+    // Write full debug info.
+    FULL,
+};
+
+} // namespace lshal
+} // namespace android
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 3d550ba..afe5d63 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -24,7 +24,7 @@
 
 #include <gtest/gtest.h>
 #include <gmock/gmock.h>
-#include <android/hardware/tests/baz/1.0/IQuux.h>
+#include <android/hardware/tests/inheritance/1.0/IChild.h>
 #include <hidl/HidlTransportSupport.h>
 #include <vintf/parse_xml.h>
 
@@ -44,6 +44,7 @@
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
+using ::android::hardware::Void;
 using android::vintf::Arch;
 using android::vintf::CompatibilityMatrix;
 using android::vintf::gCompatibilityMatrixConverter;
@@ -59,10 +60,14 @@
 namespace android {
 namespace hardware {
 namespace tests {
-namespace baz {
+namespace inheritance {
 namespace V1_0 {
 namespace implementation {
-struct Quux : android::hardware::tests::baz::V1_0::IQuux {
+struct Child : android::hardware::tests::inheritance::V1_0::IChild {
+    ::android::hardware::Return<void> doChild() override { return Void(); }
+    ::android::hardware::Return<void> doParent() override { return Void(); }
+    ::android::hardware::Return<void> doGrandparent() override { return Void(); }
+
     ::android::hardware::Return<void> debug(const hidl_handle& hh, const hidl_vec<hidl_string>& options) override {
         const native_handle_t *handle = hh.getNativeHandle();
         if (handle->numFds < 1) {
@@ -76,7 +81,7 @@
         }
         ssize_t written = write(fd, content.c_str(), content.size());
         if (written != (ssize_t)content.size()) {
-            LOG(WARNING) << "SERVER(Quux) debug writes " << written << " bytes < "
+            LOG(WARNING) << "SERVER(Child) debug writes " << written << " bytes < "
                     << content.size() << " bytes, errno = " << errno;
         }
         return Void();
@@ -85,7 +90,7 @@
 
 } // namespace implementation
 } // namespace V1_0
-} // namespace baz
+} // namespace inheritance
 } // namespace tests
 } // namespace hardware
 
@@ -124,18 +129,24 @@
 class DebugTest : public ::testing::Test {
 public:
     void SetUp() override {
-        using ::android::hardware::tests::baz::V1_0::IQuux;
-        using ::android::hardware::tests::baz::V1_0::implementation::Quux;
+        using ::android::hardware::tests::inheritance::V1_0::IChild;
+        using ::android::hardware::tests::inheritance::V1_0::IParent;
+        using ::android::hardware::tests::inheritance::V1_0::IGrandparent;
+        using ::android::hardware::tests::inheritance::V1_0::implementation::Child;
 
         err.str("");
         out.str("");
         serviceManager = new testing::NiceMock<MockServiceManager>();
-        ON_CALL(*serviceManager, get(_, _)).WillByDefault(Invoke(
-            [](const auto &iface, const auto &inst) -> ::android::hardware::Return<sp<IBase>> {
-                if (iface == IQuux::descriptor && inst == "default")
-                    return new Quux();
-                return nullptr;
-            }));
+        ON_CALL(*serviceManager, get(_, _))
+                .WillByDefault(
+                        Invoke([](const auto& iface,
+                                  const auto& inst) -> ::android::hardware::Return<sp<IBase>> {
+                            if (inst != "default") return nullptr;
+                            if (iface == IChild::descriptor || iface == IParent::descriptor ||
+                                iface == IGrandparent::descriptor)
+                                return new Child();
+                            return nullptr;
+                        }));
 
         lshal = std::make_unique<Lshal>(out, err, serviceManager, serviceManager);
     }
@@ -159,17 +170,17 @@
 
 TEST_F(DebugTest, Debug) {
     EXPECT_EQ(0u, callMain(lshal, {
-        "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux/default", "foo", "bar"
+        "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild/default", "foo", "bar"
     }));
-    EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nfoo\nbar"));
+    EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nfoo\nbar"));
     EXPECT_THAT(err.str(), IsEmpty());
 }
 
 TEST_F(DebugTest, Debug2) {
     EXPECT_EQ(0u, callMain(lshal, {
-        "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux", "baz", "quux"
+        "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild", "baz", "quux"
     }));
-    EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nbaz\nquux"));
+    EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nbaz\nquux"));
     EXPECT_THAT(err.str(), IsEmpty());
 }
 
@@ -180,6 +191,22 @@
     EXPECT_THAT(err.str(), HasSubstr("does not exist"));
 }
 
+TEST_F(DebugTest, DebugParent) {
+    EXPECT_EQ(0u, callMain(lshal, {
+        "lshal", "debug", "android.hardware.tests.inheritance@1.0::IParent", "calling parent"
+    }));
+    EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\ncalling parent"));
+    EXPECT_THAT(err.str(), IsEmpty());
+}
+
+TEST_F(DebugTest, DebugParentExclude) {
+    EXPECT_EQ(0u, callMain(lshal, {
+        "lshal", "debug", "-E", "android.hardware.tests.inheritance@1.0::IParent", "excluding"
+    }));
+    EXPECT_THAT(out.str(), IsEmpty());
+    EXPECT_THAT(err.str(), IsEmpty());
+}
+
 class MockLshal : public Lshal {
 public:
     MockLshal() {}
@@ -766,6 +793,91 @@
     EXPECT_EQ("", err.str());
 }
 
+// Fake service returned by mocked IServiceManager::get for DumpDebug.
+// The interfaceChain and getHashChain functions returns
+// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase.
+class InheritingService : public IBase {
+public:
+    explicit InheritingService(pid_t id) : mId(id) {}
+    android::hardware::Return<void> interfaceDescriptor(interfaceDescriptor_cb cb) override {
+        cb(getInterfaceName(mId));
+        return hardware::Void();
+    }
+    android::hardware::Return<void> interfaceChain(interfaceChain_cb cb) override {
+        std::vector<hidl_string> ret;
+        for (auto i = mId; i > 0; --i) {
+            ret.push_back(getInterfaceName(i));
+        }
+        ret.push_back(IBase::descriptor);
+        cb(ret);
+        return hardware::Void();
+    }
+    android::hardware::Return<void> getHashChain(getHashChain_cb cb) override {
+        std::vector<hidl_hash> ret;
+        for (auto i = mId; i > 0; --i) {
+            ret.push_back(getHashFromId(i));
+        }
+        ret.push_back(getHashFromId(0xff));
+        cb(ret);
+        return hardware::Void();
+    }
+    android::hardware::Return<void> debug(const hidl_handle& hh,
+                                          const hidl_vec<hidl_string>&) override {
+        const native_handle_t* handle = hh.getNativeHandle();
+        if (handle->numFds < 1) {
+            return Void();
+        }
+        int fd = handle->data[0];
+        std::string content = "debug info for ";
+        content += getInterfaceName(mId);
+        ssize_t written = write(fd, content.c_str(), content.size());
+        if (written != (ssize_t)content.size()) {
+            LOG(WARNING) << "SERVER(" << descriptor << ") debug writes " << written << " bytes < "
+                         << content.size() << " bytes, errno = " << errno;
+        }
+        return Void();
+    }
+
+private:
+    pid_t mId;
+};
+
+TEST_F(ListTest, DumpDebug) {
+    size_t inheritanceLevel = 3;
+    sp<IBase> service = new InheritingService(inheritanceLevel);
+
+    EXPECT_CALL(*serviceManager, list(_)).WillRepeatedly(Invoke([&](IServiceManager::list_cb cb) {
+        std::vector<hidl_string> ret;
+        for (auto i = 1; i <= inheritanceLevel; ++i) {
+            ret.push_back(getInterfaceName(i) + "/default");
+        }
+        cb(ret);
+        return hardware::Void();
+    }));
+    EXPECT_CALL(*serviceManager, get(_, _))
+            .WillRepeatedly(
+                    Invoke([&](const hidl_string&, const hidl_string& instance) -> sp<IBase> {
+                        int id = getIdFromInstanceName(instance);
+                        if (id > inheritanceLevel) return nullptr;
+                        return sp<IBase>(service);
+                    }));
+
+    const std::string expected = "[fake description 0]\n"
+                                 "Interface\n"
+                                 "a.h.foo1@1.0::IFoo/default\n"
+                                 "[See a.h.foo3@3.0::IFoo/default]\n"
+                                 "a.h.foo2@2.0::IFoo/default\n"
+                                 "[See a.h.foo3@3.0::IFoo/default]\n"
+                                 "a.h.foo3@3.0::IFoo/default\n"
+                                 "debug info for a.h.foo3@3.0::IFoo\n"
+                                 "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--types=b", "-id"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
 class ListVintfTest : public ListTest {
 public:
     virtual void SetUp() override {
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 05f43e3..25c0b19 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -326,6 +326,11 @@
 
     while(true) {
         {
+            // It would be really nice if we could read binder commands on this
+            // thread instead of needing a threadpool to be started, but for
+            // instance, if we call getAndExecuteCommand, it might be the case
+            // that another thread serves the callback, and we never get a
+            // command, so we hang indefinitely.
             std::unique_lock<std::mutex> lock(waiter->mMutex);
             using std::literals::chrono_literals::operator""s;
             waiter->mCv.wait_for(lock, 1s, [&] {
@@ -334,6 +339,8 @@
             if (waiter->mBinder != nullptr) return waiter->mBinder;
         }
 
+        ALOGW("Waited one second for %s (is service started? are binder threads started and available?)", name.c_str());
+
         // Handle race condition for lazy services. Here is what can happen:
         // - the service dies (not processed by init yet).
         // - sm processes death notification.
@@ -347,8 +354,6 @@
             return nullptr;
         }
         if (out != nullptr) return out;
-
-        ALOGW("Waited one second for %s", name.c_str());
     }
 }
 
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index ebf91f9..b46b3e8 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -387,7 +387,7 @@
     while (cur) {
         if (cur->start == start) {
             LOG_FATAL_IF(cur->free,
-                "block at offset 0x%08lX of size 0x%08lX already freed",
+                "block at offset 0x%08lX of size 0x%08X already freed",
                 cur->start*kMemoryAlign, cur->size*kMemoryAlign);
 
             // merge freed blocks together
@@ -411,7 +411,7 @@
                 }
             #endif
             LOG_FATAL_IF(!freed->free,
-                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                "freed block at offset 0x%08lX of size 0x%08X is not free!",
                 freed->start * kMemoryAlign, freed->size * kMemoryAlign);
 
             return freed;
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index b4e4a42..8d51cdc 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -50,7 +50,7 @@
              * 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
-             * IBinder::setRequestingSid, it will also return nullptr.
+             * 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.
diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h
index f66406f..c7e1e14 100644
--- a/libs/binder/include/binder/TextOutput.h
+++ b/libs/binder/include/binder/TextOutput.h
@@ -50,12 +50,18 @@
 
 // ---------------------------------------------------------------------------
 
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
 // Text output stream for printing to the log (via utils/Log.h).
 extern TextOutput& alog;
 
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
 // Text output stream for printing to stdout.
 extern TextOutput& aout;
 
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
 // Text output stream for printing to stderr.
 extern TextOutput& aerr;
 
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index e66e425..ab00914 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -36,6 +36,7 @@
     host_supported: true,
 
     export_include_dirs: [
+        "include_cpp",
         "include_ndk",
         "include_platform",
     ],
@@ -95,6 +96,17 @@
     license: "NOTICE",
 }
 
+// TODO(b/160624671): package with the aidl compiler
+ndk_headers {
+    name: "libbinder_ndk_helper_headers",
+    from: "include_cpp/android",
+    to: "android",
+    srcs: [
+        "include_cpp/android/*.h",
+    ],
+    license: "NOTICE",
+}
+
 ndk_library {
     name: "libbinder_ndk",
     symbol_file: "libbinder_ndk.map.txt",
@@ -105,6 +117,7 @@
     name: "libbinder_ndk",
     symbol_file: "libbinder_ndk.map.txt",
     export_include_dirs: [
+        "include_cpp",
         "include_ndk",
         "include_platform",
     ],
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 649faa1..d287290 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <android/binder_ibinder.h>
+#include <android/binder_ibinder_platform.h>
 #include "ibinder_internal.h"
 
 #include <android/binder_stability.h>
@@ -99,8 +100,14 @@
 
     String8 descriptor(getBinder()->getInterfaceDescriptor());
     if (descriptor != newDescriptor) {
-        LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
-                   << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+        if (getBinder()->isBinderAlive()) {
+            LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
+                       << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+        } else {
+            // b/155793159
+            LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor.c_str()
+                       << "' to dead binder.";
+        }
         return false;
     }
 
@@ -676,3 +683,29 @@
     rawBinder->setExtension(ext->getBinder());
     return STATUS_OK;
 }
+
+// platform methods follow
+
+void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) {
+    ABBinder* localBinder = binder->asABBinder();
+    if (localBinder == nullptr) {
+        LOG(FATAL) << "AIBinder_setRequestingSid must be called on a local binder";
+    }
+
+    localBinder->setRequestingSid(requestingSid);
+}
+
+const char* AIBinder_getCallingSid() {
+    return ::android::IPCThreadState::self()->getCallingSid();
+}
+
+android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder) {
+    if (binder == nullptr) return nullptr;
+    return binder->getBinder();
+}
+
+AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder) {
+    sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder);
+    AIBinder_incStrong(ndkBinder.get());
+    return ndkBinder.get();
+}
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_auto_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_auto_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_enums.h b/libs/binder/ndk/include_cpp/android/binder_enums.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_enums.h
rename to libs/binder/ndk/include_cpp/android/binder_enums.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_interface_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_interface_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 13dbec1..33763d5 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -408,6 +408,8 @@
  * This returns true if the class association succeeds. If it fails, no change is made to the
  * binder object.
  *
+ * Warning: this may fail if the binder is dead.
+ *
  * Available since API level 29.
  *
  * \param binder the object to attach the class to.
diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
new file mode 100644
index 0000000..d4feaba
--- /dev/null
+++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+#include <binder/IBinder.h>
+#endif
+
+__BEGIN_DECLS
+
+/**
+ * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This
+ * must be called on a local binder server before it is sent out to any othe
+ * process. If this is a remote binder, it will abort. If the kernel doesn't
+ * support this feature, you'll always get null from AIBinder_getCallingSid.
+ *
+ * \param binder local server binder to request security contexts on
+ */
+void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCED_IN(31);
+
+/**
+ * Returns the selinux context of the callee.
+ *
+ * In order for this to work, the following conditions must be met:
+ * - The kernel must be new enough to support this feature.
+ * - The server must have called AIBinder_setRequestingSid.
+ * - The callee must be a remote process.
+ *
+ * \return security context or null if unavailable. The lifetime of this context
+ * is the lifetime of the transaction.
+ */
+__attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
+
+__END_DECLS
+
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+
+/**
+ * Get libbinder version of binder from AIBinder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder binder with ownership retained by the client
+ * \return platform binder object
+ */
+android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder);
+
+/**
+ * Get libbinder_ndk version of binder from platform binder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder platform binder which may be from anywhere (doesn't have to be
+ * created with libbinder_ndK)
+ * \return binder with one reference count of ownership given to the client. See
+ * AIBinder_decStrong
+ */
+AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder);
+
+#endif
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index a9eba47..9b5fa26 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -95,8 +95,6 @@
     AServiceManager_addService; # apex llndk
     AServiceManager_checkService; # apex llndk
     AServiceManager_getService; # apex llndk
-  local:
-    *;
 };
 
 LIBBINDER_NDK30 { # introduced=30
@@ -111,11 +109,21 @@
     AIBinder_markVendorStability; # llndk
     AIBinder_markVintfStability; # apex llndk
     AIBinder_Class_setHandleShellCommand; # apex llndk
-  local:
-    *;
+};
+
+LIBBINDER_NDK31 { # introduced=31
+  global:
+    AIBinder_getCallingSid; # apex
+    AIBinder_setRequestingSid; # apex
 };
 
 LIBBINDER_NDK_PLATFORM {
   global:
     AParcel_getAllowFds;
+    extern "C++" {
+        AIBinder_fromPlatformBinder*;
+        AIBinder_toPlatformBinder*;
+    };
+  local:
+    *;
 };
diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
index 6e8e463..dc77467d 100644
--- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
+++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
@@ -22,6 +22,10 @@
 import IEmpty;
 
 interface IBinderNdkUnitTest {
+    int repeatInt(int a);
+
     void takeInterface(IEmpty test);
     void forceFlushCommands();
+
+    boolean getsRequestedSid();
 }
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index fd30d87..e3fdb4b 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -19,6 +19,7 @@
 #include <aidl/BnEmpty.h>
 #include <android-base/logging.h>
 #include <android/binder_ibinder_jni.h>
+#include <android/binder_ibinder_platform.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <gtest/gtest.h>
@@ -34,6 +35,7 @@
 #include <sys/prctl.h>
 #include <chrono>
 #include <condition_variable>
+#include <iostream>
 #include <mutex>
 
 using namespace android;
@@ -42,6 +44,10 @@
 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
 
 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
+    ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
+        *out = in;
+        return ndk::ScopedAStatus::ok();
+    }
     ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
         (void)empty;
         return ndk::ScopedAStatus::ok();
@@ -52,6 +58,12 @@
         android::IPCThreadState::self()->flushCommands();
         return ndk::ScopedAStatus::ok();
     }
+    ndk::ScopedAStatus getsRequestedSid(bool* out) {
+        const char* sid = AIBinder_getCallingSid();
+        std::cout << "Got security context: " << (sid ?: "null") << std::endl;
+        *out = sid != nullptr;
+        return ndk::ScopedAStatus::ok();
+    }
     binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
                                        uint32_t numArgs) override {
         for (uint32_t i = 0; i < numArgs; i++) {
@@ -66,8 +78,11 @@
     ABinderProcess_setThreadPoolMaxThreadCount(0);
 
     auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
-    binder_status_t status =
-            AServiceManager_addService(service->asBinder().get(), kBinderNdkUnitTestService);
+    auto binder = service->asBinder();
+
+    AIBinder_setRequestingSid(binder.get(), true);
+
+    binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
 
     if (status != STATUS_OK) {
         LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
@@ -274,6 +289,16 @@
     EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
 }
 
+TEST(NdkBinder, RequestedSidWorks) {
+    ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
+    std::shared_ptr<aidl::IBinderNdkUnitTest> service =
+            aidl::IBinderNdkUnitTest::fromBinder(binder);
+
+    bool gotSid = false;
+    EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
+    EXPECT_TRUE(gotSid);
+}
+
 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
     static volatile bool destroyed = false;
     static std::mutex dMutex;
@@ -308,6 +333,30 @@
     EXPECT_TRUE(destroyed);
 }
 
+TEST(NdkBinder, ConvertToPlatformBinder) {
+    for (const ndk::SpAIBinder& binder :
+         {// remote
+          ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
+          // local
+          ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
+        // convert to platform binder
+        EXPECT_NE(binder.get(), nullptr);
+        sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
+        EXPECT_NE(platformBinder.get(), nullptr);
+        auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
+        EXPECT_NE(proxy, nullptr);
+
+        // use platform binder
+        int out;
+        EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
+        EXPECT_EQ(out, 4);
+
+        // convert back
+        ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
+        EXPECT_EQ(backBinder.get(), binder.get());
+    }
+}
+
 class MyResultReceiver : public BnResultReceiver {
    public:
     Mutex mMutex;
diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp
index 68cc225..44e2fd1 100644
--- a/libs/binderthreadstate/test.cpp
+++ b/libs/binderthreadstate/test.cpp
@@ -165,7 +165,6 @@
     android::ProcessState::self()->startThreadPool();
 
     // HIDL
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
     android::hardware::configureRpcThreadpool(1, true /*callerWillJoin*/);
     sp<IHidlStuff> hidlServer = new HidlServer(thisId, otherId);
     CHECK(OK == hidlServer->registerAsService(id2name(thisId).c_str()));
@@ -176,7 +175,7 @@
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+    android::hardware::details::setTrebleTestingOverride(true);
     if (fork() == 0) {
         prctl(PR_SET_PDEATHSIG, SIGHUP);
         return server(kP1Id, kP2Id);
diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp
index 8ab09f3..b36e0de 100644
--- a/libs/vr/libpdx/fuzz/Android.bp
+++ b/libs/vr/libpdx/fuzz/Android.bp
@@ -1,5 +1,5 @@
 cc_fuzz {
-    name: "libpdx_fuzz",
+    name: "libpdx_service_dispatcher_fuzzer",
     clang: true,
     srcs: [
         "service_dispatcher_fuzzer.cpp",
@@ -15,6 +15,48 @@
     shared_libs: [
         "libutils",
         "liblog",
-	"libcutils",
+        "libcutils"
+    ],
+}
+
+cc_fuzz {
+    name: "libpdx_message_fuzzer",
+    clang: true,
+    srcs: [
+        "message_fuzzer.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    static_libs: [
+        "libpdx",
+    ],
+    shared_libs: [
+        "libutils",
+        "liblog",
+        "libcutils"
+    ],
+}
+
+cc_fuzz {
+    name: "libpdx_serialization_fuzzer",
+    clang: true,
+    srcs: [
+        "serialization_fuzzer.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    static_libs: [
+        "libpdx",
+    ],
+    shared_libs: [
+        "libutils",
+        "liblog",
+        "libcutils"
     ],
 }
diff --git a/libs/vr/libpdx/fuzz/message_fuzzer.cpp b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
new file mode 100644
index 0000000..b627045
--- /dev/null
+++ b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Authors: corbin.souffrant@leviathansecurity.com
+//          brian.balling@leviathansecurity.com
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <helpers.h>
+#include <pdx/client_channel.h>
+#include <pdx/service.h>
+#include <pdx/service_dispatcher.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/eventfd.h>
+#include <thread>
+
+using namespace android::pdx;
+
+// Fuzzer for Message object functions.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+  FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
+  std::shared_ptr<Service> service(
+      new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
+  std::shared_ptr<Channel> channel(nullptr);
+
+  // Generate a random Message object to call functions in.
+  MessageInfo info;
+  info.pid = fdp.ConsumeIntegral<int>();
+  info.tid = fdp.ConsumeIntegral<int>();
+  info.cid = fdp.ConsumeIntegral<int>();
+  info.mid = fdp.ConsumeIntegral<int>();
+  info.euid = fdp.ConsumeIntegral<int>();
+  info.egid = fdp.ConsumeIntegral<int>();
+  info.op = fdp.ConsumeIntegral<int32_t>();
+  info.flags = fdp.ConsumeIntegral<uint32_t>();
+  info.service = service.get();
+  info.channel = channel.get();
+  info.send_len = fdp.ConsumeIntegral<size_t>();
+  info.recv_len = fdp.ConsumeIntegral<size_t>();
+  info.fd_count = fdp.ConsumeIntegral<size_t>();
+  if (fdp.remaining_bytes() >= 32) {
+    std::vector<uint8_t> impulse_vec = fdp.ConsumeBytes<uint8_t>(32);
+    memcpy(info.impulse, impulse_vec.data(), 32);
+  }
+
+  Message message = Message(info);
+
+  // A bunch of getters that probably won't do much, but might as well
+  // get coverage, while we are here.
+  message.GetProcessId();
+  message.GetThreadId();
+  message.GetEffectiveUserId();
+  message.GetEffectiveGroupId();
+  message.GetChannelId();
+  message.GetMessageId();
+  message.GetOp();
+  message.GetFlags();
+  message.GetSendLength();
+  message.GetReceiveLength();
+  message.GetFileDescriptorCount();
+  message.ImpulseEnd();
+  message.replied();
+  message.IsChannelExpired();
+  message.IsServiceExpired();
+  message.GetState();
+  message.GetState();
+
+  // Some misc. functions.
+  unsigned int fd = fdp.ConsumeIntegral<unsigned int>();
+  int clear_mask = fdp.ConsumeIntegral<int>();
+  int set_mask = fdp.ConsumeIntegral<int>();
+  Status<void> status = {};
+  message.ModifyChannelEvents(clear_mask, set_mask);
+
+  // Fuzz the handle functions.
+  LocalHandle l_handle = {};
+  BorrowedHandle b_handle = {};
+  RemoteHandle r_handle = {};
+  LocalChannelHandle lc_handle = {};
+  BorrowedChannelHandle bc_handle = {};
+  RemoteChannelHandle rc_handle = {};
+  FileReference f_ref = fdp.ConsumeIntegral<int32_t>();
+  ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>();
+
+  // These don't actually modify any state in the Message or params.
+  // They can be called in any order.
+  message.PushFileHandle(b_handle);
+  message.PushFileHandle(r_handle);
+  message.PushChannelHandle(lc_handle);
+  message.PushChannelHandle(bc_handle);
+  message.PushChannelHandle(rc_handle);
+  message.GetFileHandle(f_ref, &l_handle);
+  message.GetChannelHandle(c_ref, &lc_handle);
+
+  // Can only reply once, pick at random.
+  switch (fdp.ConsumeIntegral<uint8_t>()) {
+    case 0:
+      message.ReplyFileDescriptor(fd);
+      break;
+    case 1:
+      message.Reply(status);
+      break;
+    case 2:
+      message.Reply(l_handle);
+      break;
+    case 3:
+      message.Reply(b_handle);
+      break;
+    case 4:
+      message.Reply(r_handle);
+      break;
+    case 5:
+      message.Reply(lc_handle);
+      break;
+    case 6:
+      message.Reply(bc_handle);
+      break;
+    case 7:
+      message.Reply(rc_handle);
+  }
+
+  // Fuzz the channel functions.
+  int flags = fdp.ConsumeIntegral<int>();
+  int channel_id = 0;
+  message.PushChannel(flags, channel, &channel_id);
+  message.CheckChannel(service.get(), c_ref, &channel);
+  message.CheckChannel(c_ref, &channel);
+  message.PushChannel(service.get(), flags, channel, &channel_id);
+  size_t iovec_size = sizeof(iovec);
+  struct iovec* iovecs = nullptr;
+
+  // Fuzz the read/write functions. Needs at least one iovec, plus one byte.
+  if (fdp.remaining_bytes() >= iovec_size + 1) {
+    std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size);
+    struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data());
+    std::vector<uint8_t> tmp_buf =
+        fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
+    void* buf = reinterpret_cast<void*>(tmp_buf.data());
+    size_t buf_size = fdp.ConsumeIntegral<size_t>();
+
+    // Capping num_vecs to 1024 so it doesn't allocate too much memory.
+    size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
+
+    if (num_vecs > 0)
+      iovecs = new struct iovec[num_vecs];
+    for (size_t i = 0; i < num_vecs; i++) {
+      iovecs[i] = *vector;
+    }
+
+    message.ReadAll(vector, buf_size);
+    message.WriteAll(buf, buf_size);
+    message.ReadVectorAll(vector, num_vecs);
+    message.WriteVectorAll(vector, num_vecs);
+    message.ReadVector(vector, buf_size);
+    message.WriteVector(vector, buf_size);
+  }
+
+  if (iovecs != nullptr)
+    delete[] iovecs;
+  return 0;
+}
diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
new file mode 100644
index 0000000..afde5f7
--- /dev/null
+++ b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Authors: corbin.souffrant@leviathansecurity.com
+//          brian.balling@leviathansecurity.com
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <pdx/rpc/argument_encoder.h>
+#include <pdx/rpc/array_wrapper.h>
+#include <pdx/rpc/default_initialization_allocator.h>
+#include <pdx/rpc/payload.h>
+#include <pdx/rpc/serializable.h>
+#include <pdx/rpc/serialization.h>
+#include <pdx/rpc/string_wrapper.h>
+#include <pdx/utility.h>
+
+using namespace android::pdx;
+using namespace android::pdx::rpc;
+
+struct FuzzType {
+  int a;
+  float b;
+  std::string c;
+
+  FuzzType() {}
+  FuzzType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
+
+ private:
+  PDX_SERIALIZABLE_MEMBERS(FuzzType, a, b, c);
+};
+
+// Fuzzer for Serialization operations, this is mostly just lifted from the
+// existing test cases to use fuzzed values as inputs.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload result;
+
+  // Currently, only fuzzing subset of types. In the future, may want
+  // to add more difficult to generate types like array, map, enum, etc...
+  bool b_val = fdp.ConsumeBool();
+  uint8_t u8_val = fdp.ConsumeIntegral<uint8_t>();
+  uint16_t u16_val = fdp.ConsumeIntegral<uint16_t>();
+  uint32_t u32_val = fdp.ConsumeIntegral<uint32_t>();
+  uint64_t u64_val = fdp.ConsumeIntegral<uint64_t>();
+  int8_t i8_val = fdp.ConsumeIntegral<int8_t>();
+  int16_t i16_val = fdp.ConsumeIntegral<uint16_t>();
+  int32_t i32_val = fdp.ConsumeIntegral<uint32_t>();
+  int64_t i64_val = fdp.ConsumeIntegral<uint64_t>();
+  float f_val = fdp.ConsumeFloatingPoint<float>();
+  double d_val = fdp.ConsumeFloatingPoint<double>();
+  std::string s_val = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
+  std::vector<uint8_t> vec_val =
+      fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
+  FuzzType t1_val{reinterpret_cast<int>(i32_val), f_val, s_val};
+
+  // Types need to be individually fuzzed because code path changes depending
+  // on which type is being serialized/deserialized.
+  Serialize(b_val, &result);
+  Deserialize(&b_val, &result);
+  Serialize(u8_val, &result);
+  Deserialize(&u8_val, &result);
+  Serialize(u16_val, &result);
+  Deserialize(&u16_val, &result);
+  Serialize(u32_val, &result);
+  Deserialize(&u32_val, &result);
+  Serialize(u64_val, &result);
+  Deserialize(&u64_val, &result);
+  Serialize(i8_val, &result);
+  Deserialize(&i8_val, &result);
+  Serialize(i16_val, &result);
+  Deserialize(&i16_val, &result);
+  Serialize(i32_val, &result);
+  Deserialize(&i32_val, &result);
+  Serialize(i64_val, &result);
+  Deserialize(&i64_val, &result);
+  Serialize(f_val, &result);
+  Deserialize(&f_val, &result);
+  Serialize(d_val, &result);
+  Deserialize(&d_val, &result);
+  Serialize(s_val, &result);
+  Deserialize(&s_val, &result);
+  Serialize(WrapString(s_val), &result);
+  Deserialize(&s_val, &result);
+  Serialize(vec_val, &result);
+  Deserialize(&vec_val, &result);
+  Serialize(t1_val, &result);
+  Deserialize(&t1_val, &result);
+
+  return 0;
+}
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 86d91a9..ef567c7 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -332,7 +332,8 @@
     virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
 
     /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
-    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
+    virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(
+            int32_t deviceId) = 0;
 
     /* Notifies the input reader policy that some input devices have changed
      * and provides information about all current input devices.
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index 194c665..85d7247 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -33,7 +33,7 @@
  * The pointer controller is responsible for providing synchronization and for tracking
  * display orientation changes if needed.
  */
-class PointerControllerInterface : public virtual RefBase {
+class PointerControllerInterface {
 protected:
     PointerControllerInterface() { }
     virtual ~PointerControllerInterface() { }
@@ -59,11 +59,11 @@
     /* Gets the absolute location of the pointer. */
     virtual void getPosition(float* outX, float* outY) const = 0;
 
-    enum Transition {
+    enum class Transition {
         // Fade/unfade immediately.
-        TRANSITION_IMMEDIATE,
+        IMMEDIATE,
         // Fade/unfade gradually.
-        TRANSITION_GRADUAL,
+        GRADUAL,
     };
 
     /* Fades the pointer out now. */
@@ -75,11 +75,11 @@
      * wants to ensure that the pointer becomes visible again. */
     virtual void unfade(Transition transition) = 0;
 
-    enum Presentation {
+    enum class Presentation {
         // Show the mouse pointer.
-        PRESENTATION_POINTER,
+        POINTER,
         // Show spots and a spot anchor in place of the mouse pointer.
-        PRESENTATION_SPOT,
+        SPOT,
     };
 
     /* Sets the mode of the pointer controller. */
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 2395177..da837a5 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -20,6 +20,7 @@
 
 #include "CursorButtonAccumulator.h"
 #include "CursorScrollAccumulator.h"
+#include "PointerControllerInterface.h"
 #include "TouchCursorInputMapperCommon.h"
 
 namespace android {
@@ -153,7 +154,7 @@
                 mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
                 mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
                 // Keep PointerController around in order to preserve the pointer position.
-                mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+                mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
             } else {
                 ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
             }
@@ -335,7 +336,7 @@
     int32_t displayId;
     if (mSource == AINPUT_SOURCE_MOUSE) {
         if (moved || scrolled || buttonsChanged) {
-            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+            mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
 
             if (moved) {
                 mPointerController->move(deltaX, deltaY);
@@ -345,7 +346,7 @@
                 mPointerController->setButtonState(currentButtonState);
             }
 
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+            mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
         }
 
         float x, y;
@@ -480,7 +481,7 @@
 
 void CursorInputMapper::fadePointer() {
     if (mPointerController != nullptr) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
     }
 }
 
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 05b6967..a1e9f10 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -107,7 +107,7 @@
 
     int32_t mOrientation;
 
-    sp<PointerControllerInterface> mPointerController;
+    std::shared_ptr<PointerControllerInterface> mPointerController;
 
     int32_t mButtonState;
     nsecs_t mDownTime;
diff --git a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
index efa3d6d..ca18edc 100644
--- a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
+++ b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
@@ -17,12 +17,12 @@
 #ifndef _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
 #define _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
 
+#include <stdint.h>
+
 #include "EventHub.h"
 #include "InputListener.h"
 #include "InputReaderContext.h"
 
-#include <stdint.h>
-
 namespace android {
 
 // --- Static Definitions ---
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index fb35bee..97cbad2 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -778,7 +778,7 @@
             mPointerController->setDisplayViewport(defaultViewport.value_or(mViewport));
         }
     } else {
-        mPointerController.clear();
+        mPointerController.reset();
     }
 
     if (viewportChanged || deviceModeChanged) {
@@ -1394,7 +1394,7 @@
     resetExternalStylus();
 
     if (mPointerController != nullptr) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
         mPointerController->clearSpots();
     }
 
@@ -1614,8 +1614,8 @@
     } else {
         if (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches &&
             mPointerController != nullptr) {
-            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
-            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+            mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT);
+            mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
 
             mPointerController->setButtonState(mCurrentRawState.buttonState);
             mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
@@ -2366,7 +2366,7 @@
 
     // Update the pointer presentation and spots.
     if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
-        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+        mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
         if (finishPreviousGesture || cancelPreviousGesture) {
             mPointerController->clearSpots();
         }
@@ -2378,7 +2378,7 @@
                                          mPointerController->getDisplayId());
         }
     } else {
-        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+        mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
     }
 
     // Show or hide the pointer if needed.
@@ -2388,7 +2388,7 @@
             if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH &&
                 mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) {
                 // Remind the user of where the pointer is after finishing a gesture with spots.
-                mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
+                mPointerController->unfade(PointerControllerInterface::Transition::GRADUAL);
             }
             break;
         case PointerGesture::TAP:
@@ -2399,15 +2399,15 @@
         case PointerGesture::SWIPE:
             // Unfade the pointer when the current gesture manipulates the
             // area directly under the pointer.
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+            mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
             break;
         case PointerGesture::FREEFORM:
             // Fade the pointer when the current gesture manipulates a different
             // area and there are spots to guide the user experience.
             if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
-                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+                mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
             } else {
-                mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+                mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
             }
             break;
     }
@@ -2578,7 +2578,7 @@
 
     // Remove any current spots.
     if (mPointerController != nullptr) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
         mPointerController->clearSpots();
     }
 }
@@ -3438,12 +3438,12 @@
 
     if (mPointerController != nullptr) {
         if (down || hovering) {
-            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+            mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
             mPointerController->clearSpots();
             mPointerController->setButtonState(mCurrentRawState.buttonState);
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+            mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
         } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
-            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+            mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
         }
         displayId = mPointerController->getDisplayId();
     }
@@ -3652,7 +3652,7 @@
 
 void TouchInputMapper::fadePointer() {
     if (mPointerController != nullptr) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
     }
 }
 
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index d14812a..b445981 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -444,7 +444,7 @@
     nsecs_t mDownTime;
 
     // The pointer controller, or null if the device is not a pointer.
-    sp<PointerControllerInterface> mPointerController;
+    std::shared_ptr<PointerControllerInterface> mPointerController;
 
     std::vector<VirtualKey> mVirtualKeys;
 
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 7442e68..8e80b63 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -24,11 +24,12 @@
 #include <SwitchInputMapper.h>
 #include <TestInputListener.h>
 #include <TouchInputMapper.h>
-
 #include <gtest/gtest.h>
 #include <inttypes.h>
 #include <math.h>
 
+#include <memory>
+#include <unordered_map>
 
 namespace android {
 
@@ -68,15 +69,14 @@
     int32_t mButtonState;
     int32_t mDisplayId;
 
-protected:
-    virtual ~FakePointerController() { }
-
 public:
     FakePointerController() :
         mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
         mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
     }
 
+    virtual ~FakePointerController() {}
+
     void setBounds(float minX, float minY, float maxX, float maxY) {
         mHaveBounds = true;
         mMinX = minX;
@@ -165,7 +165,7 @@
 
 class FakeInputReaderPolicy : public InputReaderPolicyInterface {
     InputReaderConfiguration mConfig;
-    KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
+    std::unordered_map<int32_t, std::shared_ptr<FakePointerController>> mPointerControllers;
     std::vector<InputDeviceInfo> mInputDevices;
     std::vector<DisplayViewport> mViewports;
     TouchAffineTransformation transform;
@@ -226,8 +226,8 @@
         }
     }
 
-    void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
-        mPointerControllers.add(deviceId, controller);
+    void setPointerController(int32_t deviceId, std::shared_ptr<FakePointerController> controller) {
+        mPointerControllers.insert_or_assign(deviceId, std::move(controller));
     }
 
     const InputReaderConfiguration* getReaderConfiguration() const {
@@ -288,8 +288,8 @@
         *outConfig = mConfig;
     }
 
-    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
-        return mPointerControllers.valueFor(deviceId);
+    virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
+        return mPointerControllers[deviceId];
     }
 
     virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
@@ -1887,9 +1887,9 @@
         ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
     }
 
-    static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
+    static void assertPosition(const FakePointerController& controller, float x, float y) {
         float actualX, actualY;
-        controller->getPosition(&actualX, &actualY);
+        controller.getPosition(&actualX, &actualY);
         ASSERT_NEAR(x, actualX, 1);
         ASSERT_NEAR(y, actualY, 1);
     }
@@ -2395,12 +2395,12 @@
 protected:
     static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
 
-    sp<FakePointerController> mFakePointerController;
+    std::shared_ptr<FakePointerController> mFakePointerController;
 
     virtual void SetUp() {
         InputMapperTest::SetUp();
 
-        mFakePointerController = new FakePointerController();
+        mFakePointerController = std::make_shared<FakePointerController>();
         mFakePolicy->setPointerController(mDevice->getId(), mFakePointerController);
     }
 
@@ -3067,7 +3067,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
             110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
 }
 
 TEST_F(CursorInputMapperTest, Process_PointerCapture) {
@@ -3096,7 +3096,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
             10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
 
     // Button press.
     process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
@@ -3135,7 +3135,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
             30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
 
     // Disable pointer capture and check that the device generation got bumped
     // and events are generated the usual way.
@@ -3156,7 +3156,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
             110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
 }
 
 TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
@@ -3185,7 +3185,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
             110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
     ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId);
 }
 
@@ -6340,7 +6340,8 @@
 
 TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
     // Setup for second display.
-    sp<FakePointerController> fakePointerController = new FakePointerController();
+    std::shared_ptr<FakePointerController> fakePointerController =
+            std::make_shared<FakePointerController>();
     fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
     fakePointerController->setPosition(100, 200);
     fakePointerController->setButtonState(0);
@@ -6401,7 +6402,8 @@
     device2->reset(ARBITRARY_TIME);
 
     // Setup PointerController.
-    sp<FakePointerController> fakePointerController = new FakePointerController();
+    std::shared_ptr<FakePointerController> fakePointerController =
+            std::make_shared<FakePointerController>();
     mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
     mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController);
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 60b3cf0..c033290 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -55,6 +55,7 @@
 #include <gui/IProducerListener.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
+#include <hidl/ServiceManagement.h>
 #include <input/IInputFlinger.h>
 #include <renderengine/RenderEngine.h>
 #include <ui/ColorSpace.h>
@@ -401,7 +402,7 @@
         // deriving the setting from the set service name, but it
         // would be brittle if the name that's not 'default' is used
         // for production purposes later on.
-        setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+        android::hardware::details::setTrebleTestingOverride(true);
     }
 }