libbinder_ndk: Add stability downgrade

This can be used to allow registering a service with a VINTF interface
without requiring a manifest declaration.

This is useful for test services or in the case of a system proxy
service that implements the same interface as the vintf service.

Bug: 183154648
Bug: 177664629
Test: atest binderStabilityTest
Change-Id: Ibd8dad46945a339b77dca70484082fda06220ee3
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 06830c0..709cf67 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -38,18 +38,30 @@
     };
 }
 
-void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) {
+void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
     // Downgrading a remote binder would require also copying the version from
     // the binder sent here. In practice though, we don't need to downgrade the
     // stability of a remote binder, since this would as an effect only restrict
     // what we can do to it.
     LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
 
-    auto stability = Category::currentFromLevel(getLocalLevel());
+    auto stability = Category::currentFromLevel(level);
     status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
+void Stability::forceDowngradeToLocalStability(const sp<IBinder>& binder) {
+    forceDowngradeToStability(binder, getLocalLevel());
+}
+
+void Stability::forceDowngradeToSystemStability(const sp<IBinder>& binder) {
+    forceDowngradeToStability(binder, Level::SYSTEM);
+}
+
+void Stability::forceDowngradeToVendorStability(const sp<IBinder>& binder) {
+    forceDowngradeToStability(binder, Level::VENDOR);
+}
+
 std::string Stability::Category::debugString() {
     return levelString(level) + " wire protocol version "
         + std::to_string(version);
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index a09e587..1831ffc 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -54,8 +54,33 @@
     // Given a binder interface at a certain stability, there may be some
     // requirements associated with that higher stability level. For instance, a
     // VINTF stability binder is required to be in the VINTF manifest. This API
-    // can be called to use that same interface within a partition.
-    static void forceDowngradeCompilationUnit(const sp<IBinder>& binder);
+    // can be called to use that same interface within the local partition.
+    static void forceDowngradeToLocalStability(const sp<IBinder>& binder);
+
+    // WARNING: The only client of
+    //      - forceDowngradeToSystemStability() and;
+    //      - korceDowngradeToVendorStability()
+    //  should be AIBinder_forceDowngradeToLocalStability().
+    //
+    // getLocalLevel() in libbinder returns Level::SYSTEM when called
+    // from libbinder_ndk (even on vendor partition). So we explicitly provide
+    // these methods for use by the NDK API:
+    //      AIBinder_forceDowngradeToLocalStability().
+    //
+    // This allows correctly downgrading the binder's stability to either system/vendor,
+    // depending on the partition.
+
+    // Given a binder interface at a certain stability, there may be some
+    // requirements associated with that higher stability level. For instance, a
+    // VINTF stability binder is required to be in the VINTF manifest. This API
+    // can be called to use that same interface within the vendor partition.
+    static void forceDowngradeToVendorStability(const sp<IBinder>& binder);
+
+    // Given a binder interface at a certain stability, there may be some
+    // requirements associated with that higher stability level. For instance, a
+    // VINTF stability binder is required to be in the VINTF manifest. This API
+    // can be called to use that same interface within the system partition.
+    static void forceDowngradeToSystemStability(const sp<IBinder>& binder);
 
     // WARNING: Below APIs are only ever expected to be called by auto-generated code.
     //     Instead of calling them, you should set the stability of a .aidl interface
@@ -146,6 +171,9 @@
     // returns the stability according to how this was built
     static Level getLocalLevel();
 
+    // Downgrades binder stability to the specified level.
+    static void forceDowngradeToStability(const sp<IBinder>& binder, Level level);
+
     enum {
       REPR_NONE = 0,
       REPR_LOG = 1,
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index ce7255e..0973f2c 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -45,6 +45,18 @@
     AIBinder_markVendorStability(binder);
 }
 
+/**
+ * Given a binder interface at a certain stability, there may be some
+ * requirements associated with that higher stability level. For instance, a
+ * VINTF stability binder is required to be in the VINTF manifest. This API
+ * can be called to use that same interface within the vendor partition.
+ */
+void AIBinder_forceDowngradeToVendorStability(AIBinder* binder);
+
+static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) {
+    AIBinder_forceDowngradeToVendorStability(binder);
+}
+
 #else  // defined(__ANDROID_VENDOR__)
 
 enum {
@@ -62,6 +74,18 @@
     AIBinder_markSystemStability(binder);
 }
 
+/**
+ * Given a binder interface at a certain stability, there may be some
+ * requirements associated with that higher stability level. For instance, a
+ * VINTF stability binder is required to be in the VINTF manifest. This API
+ * can be called to use that same interface within the system partition.
+ */
+void AIBinder_forceDowngradeToSystemStability(AIBinder* binder);
+
+static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) {
+    AIBinder_forceDowngradeToSystemStability(binder);
+}
+
 #endif  // defined(__ANDROID_VENDOR__)
 
 /**
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index f1db653..67c85b6 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -127,6 +127,9 @@
     AServiceManager_tryUnregister; # llndk
     AServiceManager_reRegister; # llndk
 
+    AIBinder_forceDowngradeToSystemStability; # apex
+    AIBinder_forceDowngradeToVendorStability; # llndk
+
     AIBinder_Class_getDescriptor;
     AIBinder_Weak_clone;
     AIBinder_Weak_lt;
diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp
index a5b3ece..7eafb9c 100644
--- a/libs/binder/ndk/stability.cpp
+++ b/libs/binder/ndk/stability.cpp
@@ -31,7 +31,7 @@
 #error libbinder_ndk should only be built in a system context
 #endif
 
-// explicit extern because symbol is only declared in header when __ANDROID_VNDK__
+// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__
 extern "C" void AIBinder_markVendorStability(AIBinder* binder) {
     Stability::markVndk(binder->getBinder().get());
 }
@@ -43,3 +43,12 @@
 void AIBinder_markVintfStability(AIBinder* binder) {
     Stability::markVintf(binder->getBinder().get());
 }
+
+// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__
+extern "C" void AIBinder_forceDowngradeToVendorStability(AIBinder* binder) {
+    Stability::forceDowngradeToVendorStability(binder->getBinder());
+}
+
+void AIBinder_forceDowngradeToSystemStability(AIBinder* binder) {
+    Stability::forceDowngradeToSystemStability(binder->getBinder());
+}
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 4270540..dbd3f4e 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <android/binder_libbinder.h>
 #include <android/binder_manager.h>
 #include <android/binder_stability.h>
 #include <binder/Binder.h>
@@ -137,7 +138,18 @@
     EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder));
 
     // silly to do this after already using the binder, but it's for the test
-    Stability::forceDowngradeCompilationUnit(someBinder);
+    Stability::forceDowngradeToLocalStability(someBinder);
+
+    EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder));
+}
+
+TEST(BinderStability, NdkForceDowngradeStability) {
+    sp<IBinder> someBinder = BadStableBinder::vintf();
+
+    EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder));
+
+    // silly to do this after already using the binder, but it's for the test
+    AIBinder_forceDowngradeToLocalStability(AIBinder_fromPlatformBinder(someBinder));
 
     EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder));
 }