Merge "servicemanager: rely on auto unlinkToDeath" into stage-aosp-master
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 79f345b..af9ce78 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -44,10 +44,12 @@
 #include <unistd.h>
 
 #include <chrono>
+#include <cmath>
 #include <fstream>
 #include <functional>
 #include <future>
 #include <memory>
+#include <numeric>
 #include <regex>
 #include <set>
 #include <string>
@@ -1232,6 +1234,45 @@
     }
 }
 
+static void DumpExternalFragmentationInfo() {
+    struct stat st;
+    if (stat("/proc/buddyinfo", &st) != 0) {
+        MYLOGE("Unable to dump external fragmentation info\n");
+        return;
+    }
+
+    printf("------ EXTERNAL FRAGMENTATION INFO ------\n");
+    std::ifstream ifs("/proc/buddyinfo");
+    auto unusable_index_regex = std::regex{"Node\\s+([0-9]+),\\s+zone\\s+(\\S+)\\s+(.*)"};
+    for (std::string line; std::getline(ifs, line);) {
+        std::smatch match_results;
+        if (std::regex_match(line, match_results, unusable_index_regex)) {
+            std::stringstream free_pages(std::string{match_results[3]});
+            std::vector<int> free_pages_per_order(std::istream_iterator<int>{free_pages},
+                                                  std::istream_iterator<int>());
+
+            int total_free_pages = 0;
+            for (size_t i = 0; i < free_pages_per_order.size(); i++) {
+                total_free_pages += (free_pages_per_order[i] * std::pow(2, i));
+            }
+
+            printf("Node %s, zone %8s", match_results[1].str().c_str(),
+                   match_results[2].str().c_str());
+
+            int usable_free_pages = total_free_pages;
+            for (size_t i = 0; i < free_pages_per_order.size(); i++) {
+                auto unusable_index = (total_free_pages - usable_free_pages) /
+                        static_cast<double>(total_free_pages);
+                printf(" %5.3f", unusable_index);
+                usable_free_pages -= (free_pages_per_order[i] * std::pow(2, i));
+            }
+
+            printf("\n");
+        }
+    }
+    printf("\n");
+}
+
 // Dumps various things. Returns early with status USER_CONSENT_DENIED if user denies consent
 // via the consent they are shown. Ignores other errors that occur while running various
 // commands. The consent checking is currently done around long running tasks, which happen to
@@ -1258,7 +1299,7 @@
     DumpFile("ZONEINFO", "/proc/zoneinfo");
     DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo");
     DumpFile("BUDDYINFO", "/proc/buddyinfo");
-    DumpFile("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
+    DumpExternalFragmentationInfo();
 
     DumpFile("KERNEL WAKE SOURCES", "/d/wakeup_sources");
     DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 73780ec..0212bc5 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -275,7 +275,7 @@
             writer.StartEntry("primary.prof", ZipWriter::kCompress);
             writer.FinishEntry();
             writer.Finish();
-            close(fd);
+            fclose(file);
           }
 
         // Create the app user data.
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 1537e69..dec75f5 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -38,7 +38,7 @@
     virtual status_t    transact(   uint32_t code,
                                     const Parcel& data,
                                     Parcel* reply,
-                                    uint32_t flags = 0);
+                                    uint32_t flags = 0) final;
 
     // NOLINTNEXTLINE(google-default-arguments)
     virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index e71541b..28599f4 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -45,7 +45,7 @@
     virtual status_t    transact(   uint32_t code,
                                     const Parcel& data,
                                     Parcel* reply,
-                                    uint32_t flags = 0);
+                                    uint32_t flags = 0) final;
 
     // NOLINTNEXTLINE(google-default-arguments)
     virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 1beacdf..734a928 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-cc_library {
+cc_library_shared {
     name: "libbinder_ndk",
 
     export_include_dirs: [
         "include_ndk",
-        "include_apex",
+        "include_platform",
     ],
 
     cflags: [
@@ -80,6 +80,6 @@
     symbol_file: "libbinder_ndk.map.txt",
     export_include_dirs: [
         "include_ndk",
-        "include_apex",
+        "include_platform",
     ],
 }
diff --git a/libs/binder/ndk/include_apex/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
similarity index 100%
rename from libs/binder/ndk/include_apex/android/binder_manager.h
rename to libs/binder/ndk/include_platform/android/binder_manager.h
diff --git a/libs/binder/ndk/include_apex/android/binder_process.h b/libs/binder/ndk/include_platform/android/binder_process.h
similarity index 100%
rename from libs/binder/ndk/include_apex/android/binder_process.h
rename to libs/binder/ndk/include_platform/android/binder_process.h
diff --git a/libs/binder/ndk/include_apex/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
similarity index 100%
rename from libs/binder/ndk/include_apex/android/binder_stability.h
rename to libs/binder/ndk/include_platform/android/binder_stability.h
diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp
index abafe1f..a5b3ece 100644
--- a/libs/binder/ndk/stability.cpp
+++ b/libs/binder/ndk/stability.cpp
@@ -27,6 +27,10 @@
 #error libbinder_ndk should only be built in a system context
 #endif
 
+#ifdef __ANDROID_NDK__
+#error libbinder_ndk should only be built in a system context
+#endif
+
 // explicit extern because symbol is only declared in header when __ANDROID_VNDK__
 extern "C" void AIBinder_markVendorStability(AIBinder* binder) {
     Stability::markVndk(binder->getBinder().get());
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index 8cd4e03..bb1fe2f 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -44,10 +44,10 @@
         "libandroid_runtime_lazy",
         "libbase",
         "libbinder",
+        "libbinder_ndk",
         "libutils",
     ],
     static_libs: [
-        "libbinder_ndk",
         "test_libbinder_ndk_library",
     ],
 }
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index d59a40d..bc457ce 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -142,7 +142,6 @@
     name: "binderStabilityTestIface",
     srcs: [
         "IBinderStabilityTest.aidl",
-        "IBinderStabilityTestSub.aidl",
     ],
 }
 
diff --git a/libs/binder/tests/IBinderStabilityTest.aidl b/libs/binder/tests/IBinderStabilityTest.aidl
index 9559196..36e1c2c 100644
--- a/libs/binder/tests/IBinderStabilityTest.aidl
+++ b/libs/binder/tests/IBinderStabilityTest.aidl
@@ -14,34 +14,32 @@
  * limitations under the License.
  */
 
-import IBinderStabilityTestSub;
-
 // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
 // THIS IS ONLY FOR TESTING!
 interface IBinderStabilityTest {
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    void sendBinder(IBinderStabilityTestSub binder);
+    void sendBinder(IBinder binder);
 
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    void sendAndCallBinder(IBinderStabilityTestSub binder);
+    void sendAndCallBinder(IBinder binder);
 
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    IBinderStabilityTestSub returnNoStabilityBinder();
+    IBinder returnNoStabilityBinder();
 
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    IBinderStabilityTestSub returnLocalStabilityBinder();
+    IBinder returnLocalStabilityBinder();
 
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    IBinderStabilityTestSub returnVintfStabilityBinder();
+    IBinder returnVintfStabilityBinder();
 
     // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
     // THIS IS ONLY FOR TESTING!
-    IBinderStabilityTestSub returnVendorStabilityBinder();
+    IBinder returnVendorStabilityBinder();
 }
 // DO NOT EVER IN A MILLION YEARS WRITE AN INTERFACE LIKE THIS!
 // THIS IS ONLY FOR TESTING!
diff --git a/libs/binder/tests/IBinderStabilityTestSub.aidl b/libs/binder/tests/IBinderStabilityTestSub.aidl
deleted file mode 100644
index a81ebf9..0000000
--- a/libs/binder/tests/IBinderStabilityTestSub.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-interface IBinderStabilityTestSub {
-    void userDefinedTransaction();
-}
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 936b821..0336b9e 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -26,9 +26,7 @@
 
 #include <sys/prctl.h>
 
-#include "aidl/BnBinderStabilityTestSub.h"
 #include "aidl/BnBinderStabilityTest.h"
-#include "BnBinderStabilityTestSub.h"
 #include "BnBinderStabilityTest.h"
 
 using namespace android;
@@ -36,167 +34,217 @@
 using android::binder::Status;
 using android::internal::Stability; // for testing only!
 
-const String16 kNoStabilityServer = String16("binder_stability_test_service_low");
-const String16 kCompilationUnitServer = String16("binder_stability_test_service_compl");
-const String16 kVintfServer = String16("binder_stability_test_service_vintf");
+const String16 kSystemStabilityServer = String16("binder_stability_test_service_system");
 
-const String16 kCompilationUnitNdkServer = String16("binder_stability_test_service_compl");
-
-class BadStabilityTestSub : public BnBinderStabilityTestSub {
+// This is handwritten so that we can test different stability levels w/o having the AIDL
+// compiler assign them. Hand-writing binder interfaces is considered a bad practice
+// sanity reasons. YOU SHOULD DEFINE AN AIDL INTERFACE INSTEAD!
+class BadStableBinder : public BBinder {
 public:
-    Status userDefinedTransaction() {
-        return Status::ok();
+    static constexpr uint32_t USER_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION;
+    static String16 kDescriptor;
+
+    bool gotUserTransaction = false;
+
+    static status_t doUserTransaction(const sp<IBinder>& binder) {
+        Parcel data, reply;
+        data.writeInterfaceToken(kDescriptor);
+        return binder->transact(USER_TRANSACTION, data, &reply, 0/*flags*/);
     }
 
-    static sp<IBinderStabilityTestSub> system() {
-        sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
-        // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
-        // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
-        Stability::markCompilationUnit(iface.get()); // <- BAD, NO! DO NOT COPY
+    status_t onTransact(uint32_t code,
+            const Parcel& data, Parcel* reply, uint32_t flags) override {
+        if (code == USER_TRANSACTION) {
+            // not interested in this kind of stability. Make sure
+            // we have a test failure
+            LOG_ALWAYS_FATAL_IF(!data.enforceInterface(kDescriptor));
+
+            gotUserTransaction = true;
+
+            ALOGE("binder stability: Got user transaction");
+            return OK;
+        }
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+
+    static sp<BadStableBinder> undef() {
+        sp<BadStableBinder> iface = new BadStableBinder();
         return iface;
     }
 
-    static sp<IBinderStabilityTestSub> vintf() {
-        sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
-        // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
-        // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
-        Stability::markVintf(iface.get()); // <- BAD, NO! DO NOT COPY
+    static sp<BadStableBinder> system() {
+        sp<BadStableBinder> iface = new BadStableBinder();
+        Stability::markCompilationUnit(iface.get()); // <- for test only
         return iface;
     }
 
-    static sp<IBinderStabilityTestSub> vendor() {
-        sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
-        // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
-        // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
-        Stability::markVndk(iface.get()); // <- BAD, NO! DO NOT COPY
+    static sp<BadStableBinder> vintf() {
+        sp<BadStableBinder> iface = new BadStableBinder();
+        Stability::markVintf(iface.get()); // <- for test only
+        return iface;
+    }
+
+    static sp<BadStableBinder> vendor() {
+        sp<BadStableBinder> iface = new BadStableBinder();
+        Stability::markVndk(iface.get()); // <- for test only
         return iface;
     }
 };
+String16 BadStableBinder::kDescriptor = String16("BadStableBinder.test");
 
 // NO! NO! NO! Do not even think of doing something like this!
 // This is for testing! If a class like this was actually used in production,
 // it would ruin everything!
-class BadStabilityTester : public BnBinderStabilityTest {
+class MyBinderStabilityTest : public BnBinderStabilityTest {
 public:
-    Status sendBinder(const sp<IBinderStabilityTestSub>& /*binder*/) override {
+    Status sendBinder(const sp<IBinder>& /*binder*/) override {
         return Status::ok();
     }
-    Status sendAndCallBinder(const sp<IBinderStabilityTestSub>& binder) override {
-        Stability::debugLogStability("sendAndCallBinder got binder", IInterface::asBinder(binder));
-        return binder->userDefinedTransaction();
+    Status sendAndCallBinder(const sp<IBinder>& binder) override {
+        Stability::debugLogStability("sendAndCallBinder got binder", binder);
+        return Status::fromExceptionCode(BadStableBinder::doUserTransaction(binder));
     }
-    Status returnNoStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
-        *_aidl_return = new BadStabilityTestSub();
+    Status returnNoStabilityBinder(sp<IBinder>* _aidl_return) override {
+        *_aidl_return = BadStableBinder::undef();
         return Status::ok();
     }
-    Status returnLocalStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
-        *_aidl_return = BadStabilityTestSub::system();
+    Status returnLocalStabilityBinder(sp<IBinder>* _aidl_return) override {
+        *_aidl_return = BadStableBinder::system();
         return Status::ok();
     }
-    Status returnVintfStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
-        *_aidl_return = BadStabilityTestSub::vintf();
+    Status returnVintfStabilityBinder(sp<IBinder>* _aidl_return) override {
+        *_aidl_return = BadStableBinder::vintf();
         return Status::ok();
     }
-    Status returnVendorStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
-        *_aidl_return = BadStabilityTestSub::vendor();
+    Status returnVendorStabilityBinder(sp<IBinder>* _aidl_return) override {
+        *_aidl_return = BadStableBinder::vendor();
         return Status::ok();
     }
 };
 
-void checkSystemStabilityBinder(const sp<IBinderStabilityTest>& complServer) {
-    EXPECT_TRUE(complServer->sendBinder(new BadStabilityTestSub()).isOk());
-    EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::system()).isOk());
-    EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::vintf()).isOk());
-    EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::vendor()).isOk());
+TEST(BinderStability, CantCallVendorBinderInSystemContext) {
+    sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
+    auto server = interface_cast<IBinderStabilityTest>(serverBinder);
 
-    EXPECT_TRUE(complServer->sendAndCallBinder(new BadStabilityTestSub()).isOk());
-    EXPECT_TRUE(complServer->sendAndCallBinder(BadStabilityTestSub::system()).isOk());
-    EXPECT_TRUE(complServer->sendAndCallBinder(BadStabilityTestSub::vintf()).isOk());
+    ASSERT_NE(nullptr, server.get());
+    ASSERT_NE(nullptr, IInterface::asBinder(server)->remoteBinder());
 
-    // !!! user-defined transaction may not be stable for remote server !!!
-    EXPECT_FALSE(complServer->sendAndCallBinder(BadStabilityTestSub::vendor()).isOk());
+    EXPECT_TRUE(server->sendBinder(BadStableBinder::undef()).isOk());
+    EXPECT_TRUE(server->sendBinder(BadStableBinder::system()).isOk());
+    EXPECT_TRUE(server->sendBinder(BadStableBinder::vintf()).isOk());
+    EXPECT_TRUE(server->sendBinder(BadStableBinder::vendor()).isOk());
 
-    sp<IBinderStabilityTestSub> out;
-    EXPECT_TRUE(complServer->returnNoStabilityBinder(&out).isOk());
+    {
+        sp<BadStableBinder> binder = BadStableBinder::undef();
+        EXPECT_TRUE(server->sendAndCallBinder(binder).isOk());
+        EXPECT_TRUE(binder->gotUserTransaction);
+    }
+    {
+        sp<BadStableBinder> binder = BadStableBinder::system();
+        EXPECT_TRUE(server->sendAndCallBinder(binder).isOk());
+        EXPECT_TRUE(binder->gotUserTransaction);
+    }
+    {
+        sp<BadStableBinder> binder = BadStableBinder::vintf();
+        EXPECT_TRUE(server->sendAndCallBinder(binder).isOk());
+        EXPECT_TRUE(binder->gotUserTransaction);
+    }
+    {
+        // !!! user-defined transaction may not be stable for remote server !!!
+        // !!! so, it does not work !!!
+        sp<BadStableBinder> binder = BadStableBinder::vendor();
+        EXPECT_EQ(BAD_TYPE, server->sendAndCallBinder(binder).exceptionCode());
+        EXPECT_FALSE(binder->gotUserTransaction);
+    }
+
+    sp<IBinder> out;
+    EXPECT_TRUE(server->returnNoStabilityBinder(&out).isOk());
     ASSERT_NE(nullptr, out.get());
-    EXPECT_EQ(OK, IInterface::asBinder(out)->pingBinder());
-    EXPECT_TRUE(out->userDefinedTransaction().isOk());
+    EXPECT_EQ(OK, out->pingBinder());
+    EXPECT_EQ(OK, BadStableBinder::doUserTransaction(out));
 
-    EXPECT_TRUE(complServer->returnLocalStabilityBinder(&out).isOk());
+    EXPECT_TRUE(server->returnLocalStabilityBinder(&out).isOk());
     ASSERT_NE(nullptr, out.get());
-    EXPECT_EQ(OK, IInterface::asBinder(out)->pingBinder());
-    EXPECT_TRUE(out->userDefinedTransaction().isOk());
+    EXPECT_EQ(OK, out->pingBinder());
+    EXPECT_EQ(OK, BadStableBinder::doUserTransaction(out));
 
-    EXPECT_TRUE(complServer->returnVintfStabilityBinder(&out).isOk());
+    EXPECT_TRUE(server->returnVintfStabilityBinder(&out).isOk());
     ASSERT_NE(nullptr, out.get());
-    EXPECT_EQ(OK, IInterface::asBinder(out)->pingBinder());
-    EXPECT_TRUE(out->userDefinedTransaction().isOk());
+    EXPECT_EQ(OK, out->pingBinder());
+    EXPECT_EQ(OK, BadStableBinder::doUserTransaction(out));
 
-    EXPECT_TRUE(complServer->returnVendorStabilityBinder(&out).isOk());
+    EXPECT_TRUE(server->returnVendorStabilityBinder(&out).isOk());
     ASSERT_NE(nullptr, out.get());
 
     // !!! libbinder-defined transaction works !!!
-    EXPECT_EQ(OK, IInterface::asBinder(out)->pingBinder());
+    EXPECT_EQ(OK, out->pingBinder());
 
     // !!! user-defined transaction may not be stable !!!
-    EXPECT_FALSE(out->userDefinedTransaction().isOk());
+    // !!! so, it does not work !!!
+    EXPECT_EQ(BAD_TYPE, BadStableBinder::doUserTransaction(out));
 }
 
-TEST(BinderStability, RemoteNoStabilityServer) {
-    sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kNoStabilityServer);
-    auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder);
+// This is handwritten so that we can test different stability levels w/o having the AIDL
+// compiler assign them. Hand-writing binder interfaces is considered a bad practice
+// sanity reasons. YOU SHOULD DEFINE AN AIDL INTERFACE INSTEAD!
 
-    ASSERT_NE(nullptr, remoteServer.get());
-    ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder());
-
-    checkSystemStabilityBinder(remoteServer);
-}
-
-TEST(BinderStability, RemoteLowStabilityServer) {
-    sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kCompilationUnitServer);
-    auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder);
-
-    ASSERT_NE(nullptr, remoteServer.get());
-    ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder());
-
-    checkSystemStabilityBinder(remoteServer);
-}
-
-TEST(BinderStability, RemoteVintfServer) {
-    sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kVintfServer);
-    auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder);
-
-    ASSERT_NE(nullptr, remoteServer.get());
-    ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder());
-
-    checkSystemStabilityBinder(remoteServer);
-}
-
-class NdkBadStabilityTestSub : public aidl::BnBinderStabilityTestSub {
-    ScopedAStatus userDefinedTransaction() {
-        return ScopedAStatus::ok();
-    }
+struct NdkBinderStable_DataClass {
+    bool gotUserTransaction = false;
 };
+void* NdkBadStableBinder_Class_onCreate(void* args) {
+    LOG_ALWAYS_FATAL_IF(args != nullptr, "Takes no args");
+    return static_cast<void*>(new NdkBinderStable_DataClass);
+}
+void NdkBadStableBinder_Class_onDestroy(void* userData) {
+    delete static_cast<NdkBinderStable_DataClass*>(userData);
+}
+NdkBinderStable_DataClass* NdkBadStableBinder_getUserData(AIBinder* binder) {
+    LOG_ALWAYS_FATAL_IF(binder == nullptr);
+    void* userData = AIBinder_getUserData(binder);
+    LOG_ALWAYS_FATAL_IF(userData == nullptr, "null data - binder is remote?");
+
+    return static_cast<NdkBinderStable_DataClass*>(userData);
+}
+binder_status_t NdkBadStableBinder_Class_onTransact(
+    AIBinder* binder, transaction_code_t code, const AParcel* /*in*/, AParcel* /*out*/) {
+
+    if (code == BadStableBinder::USER_TRANSACTION) {
+        ALOGE("ndk binder stability: Got user transaction");
+        NdkBadStableBinder_getUserData(binder)->gotUserTransaction = true;
+        return STATUS_OK;
+    }
+
+    return STATUS_UNKNOWN_TRANSACTION;
+}
+
+static AIBinder_Class* kNdkBadStableBinder =
+    AIBinder_Class_define(String8(BadStableBinder::kDescriptor).c_str(),
+                          NdkBadStableBinder_Class_onCreate,
+                          NdkBadStableBinder_Class_onDestroy,
+                          NdkBadStableBinder_Class_onTransact);
+
 // for testing only to get around __ANDROID_VNDK__ guard.
 extern "C" void AIBinder_markVendorStability(AIBinder* binder); // <- BAD DO NOT COPY
 
-TEST(BinderStability, NdkClientOfRemoteServer) {
+TEST(BinderStability, NdkCantCallVendorBinderInSystemContext) {
     SpAIBinder binder = SpAIBinder(AServiceManager_getService(
-        String8(kCompilationUnitServer).c_str()));
+        String8(kSystemStabilityServer).c_str()));
 
     std::shared_ptr<aidl::IBinderStabilityTest> remoteServer =
         aidl::IBinderStabilityTest::fromBinder(binder);
 
     ASSERT_NE(nullptr, remoteServer.get());
 
-    std::shared_ptr<aidl::IBinderStabilityTestSub> vendor = SharedRefBase::make<NdkBadStabilityTestSub>();
+    SpAIBinder comp = SpAIBinder(AIBinder_new(kNdkBadStableBinder, nullptr /*args*/));
+    EXPECT_TRUE(remoteServer->sendBinder(comp).isOk());
+    EXPECT_TRUE(remoteServer->sendAndCallBinder(comp).isOk());
+    EXPECT_TRUE(NdkBadStableBinder_getUserData(comp.get())->gotUserTransaction);
 
-    // TODO: not ideal: binder must be held once it is marked
-    SpAIBinder vendorBinder = vendor->asBinder();
-    AIBinder_markVendorStability(vendorBinder.get());
-
+    SpAIBinder vendor = SpAIBinder(AIBinder_new(kNdkBadStableBinder, nullptr /*args*/));
+    AIBinder_markVendorStability(vendor.get());
     EXPECT_TRUE(remoteServer->sendBinder(vendor).isOk());
     EXPECT_FALSE(remoteServer->sendAndCallBinder(vendor).isOk());
+    EXPECT_FALSE(NdkBadStableBinder_getUserData(vendor.get())->gotUserTransaction);
 }
 
 class MarksStabilityInConstructor : public BBinder {
@@ -227,6 +275,14 @@
     ASSERT_TRUE(MarksStabilityInConstructor::gDestructed);
 }
 
+TEST(BinderStability, RemarkDies) {
+    ASSERT_DEATH({
+        sp<IBinder> binder = new BBinder();
+        Stability::markCompilationUnit(binder.get()); // <-- only called for tests
+        Stability::markVndk(binder.get()); // <-- only called for tests
+    }, "Should only mark known object.");
+}
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
 
@@ -234,16 +290,8 @@
         // child process
         prctl(PR_SET_PDEATHSIG, SIGHUP);
 
-        sp<IBinder> noStability = new BadStabilityTester;
-        android::defaultServiceManager()->addService(kNoStabilityServer, noStability);
-
-        sp<IBinder> compil = new BadStabilityTester;
-        Stability::markCompilationUnit(compil.get());
-        android::defaultServiceManager()->addService(kCompilationUnitServer, compil);
-
-        sp<IBinder> vintf = new BadStabilityTester;
-        Stability::markVintf(vintf.get());
-        android::defaultServiceManager()->addService(kVintfServer, vintf);
+        sp<IBinder> server = new MyBinderStabilityTest;
+        android::defaultServiceManager()->addService(kSystemStabilityServer, server);
 
         IPCThreadState::self()->joinThreadPool(true);
         exit(1);  // should not reach