Loading libs/binder/Stability.cpp +30 −7 Original line number Diff line number Diff line Loading @@ -38,6 +38,18 @@ Stability::Category Stability::Category::currentFromLevel(Level level) { }; } void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) { // 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()); status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } std::string Stability::Category::debugString() { return levelString(level) + " wire protocol version " + std::to_string(version); Loading @@ -45,13 +57,13 @@ std::string Stability::Category::debugString() { void Stability::markCompilationUnit(IBinder* binder) { auto stability = Category::currentFromLevel(getLocalLevel()); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } void Stability::markVintf(IBinder* binder) { auto stability = Category::currentFromLevel(Level::VINTF); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } Loading @@ -62,7 +74,7 @@ void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& bin void Stability::markVndk(IBinder* binder) { auto stability = Category::currentFromLevel(Level::VENDOR); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } Loading @@ -72,7 +84,7 @@ bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) { void Stability::tryMarkCompilationUnit(IBinder* binder) { auto stability = Category::currentFromLevel(getLocalLevel()); (void) setRepr(binder, stability.repr(), false /*log*/); (void) setRepr(binder, stability.repr(), REPR_NONE); } Stability::Level Stability::getLocalLevel() { Loading @@ -94,7 +106,10 @@ Stability::Level Stability::getLocalLevel() { #endif } status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) { bool log = flags & REPR_LOG; bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE; auto current = getCategory(binder); auto setting = Category::fromRepr(representation); Loading Loading @@ -129,7 +144,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { return BAD_TYPE; } if (current.repr() != 0 && current != setting) { if (current == setting) return OK; bool hasAlreadyBeenSet = current.repr() != 0; bool isAllowedDowngrade = allowDowngrade && check(current, setting.level); if (hasAlreadyBeenSet && !isAllowedDowngrade) { if (log) { ALOGE("Interface being set with %s but it is already marked as %s", setting.debugString().c_str(), Loading @@ -138,7 +157,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { return BAD_TYPE; } if (current == setting) return OK; if (isAllowedDowngrade) { ALOGI("Interface set with %s downgraded to %s stability", current.debugString().c_str(), setting.debugString().c_str()); } BBinder* local = binder->localBinder(); if (local != nullptr) { Loading libs/binder/include/binder/Stability.h +15 −3 Original line number Diff line number Diff line Loading @@ -49,10 +49,17 @@ namespace internal { // that it knows how to process. The summary of stability of a binder is // represented by a Stability::Category object. // WARNING: These 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 class Stability final { public: // 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); // 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 // WARNING: This is only ever expected to be called by auto-generated code. You likely want to // change or modify the stability class of the interface you are using. // This must be called as soon as the binder in question is constructed. No thread safety Loading Loading @@ -139,9 +146,14 @@ private: // returns the stability according to how this was built static Level getLocalLevel(); enum { REPR_NONE = 0, REPR_LOG = 1, REPR_ALLOW_DOWNGRADE = 2, }; // applies stability to binder if stability level is known __attribute__((warn_unused_result)) static status_t setRepr(IBinder* binder, int32_t representation, bool log); static status_t setRepr(IBinder* binder, int32_t representation, uint32_t flags); // get stability information as encoded on the wire static Category getCategory(IBinder* binder); Loading libs/binder/tests/binderStabilityTest.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,17 @@ TEST(BinderStability, OnlyVintfStabilityBinderNeedsVintfDeclaration) { EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf())); } TEST(BinderStability, ForceDowngradeStability) { 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 Stability::forceDowngradeCompilationUnit(someBinder); EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder)); } TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) { sp<IBinder> vintfServer = BadStableBinder::vintf(); Loading Loading
libs/binder/Stability.cpp +30 −7 Original line number Diff line number Diff line Loading @@ -38,6 +38,18 @@ Stability::Category Stability::Category::currentFromLevel(Level level) { }; } void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) { // 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()); status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } std::string Stability::Category::debugString() { return levelString(level) + " wire protocol version " + std::to_string(version); Loading @@ -45,13 +57,13 @@ std::string Stability::Category::debugString() { void Stability::markCompilationUnit(IBinder* binder) { auto stability = Category::currentFromLevel(getLocalLevel()); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } void Stability::markVintf(IBinder* binder) { auto stability = Category::currentFromLevel(Level::VINTF); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } Loading @@ -62,7 +74,7 @@ void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& bin void Stability::markVndk(IBinder* binder) { auto stability = Category::currentFromLevel(Level::VENDOR); status_t result = setRepr(binder, stability.repr(), true /*log*/); status_t result = setRepr(binder, stability.repr(), REPR_LOG); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } Loading @@ -72,7 +84,7 @@ bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) { void Stability::tryMarkCompilationUnit(IBinder* binder) { auto stability = Category::currentFromLevel(getLocalLevel()); (void) setRepr(binder, stability.repr(), false /*log*/); (void) setRepr(binder, stability.repr(), REPR_NONE); } Stability::Level Stability::getLocalLevel() { Loading @@ -94,7 +106,10 @@ Stability::Level Stability::getLocalLevel() { #endif } status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) { bool log = flags & REPR_LOG; bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE; auto current = getCategory(binder); auto setting = Category::fromRepr(representation); Loading Loading @@ -129,7 +144,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { return BAD_TYPE; } if (current.repr() != 0 && current != setting) { if (current == setting) return OK; bool hasAlreadyBeenSet = current.repr() != 0; bool isAllowedDowngrade = allowDowngrade && check(current, setting.level); if (hasAlreadyBeenSet && !isAllowedDowngrade) { if (log) { ALOGE("Interface being set with %s but it is already marked as %s", setting.debugString().c_str(), Loading @@ -138,7 +157,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) { return BAD_TYPE; } if (current == setting) return OK; if (isAllowedDowngrade) { ALOGI("Interface set with %s downgraded to %s stability", current.debugString().c_str(), setting.debugString().c_str()); } BBinder* local = binder->localBinder(); if (local != nullptr) { Loading
libs/binder/include/binder/Stability.h +15 −3 Original line number Diff line number Diff line Loading @@ -49,10 +49,17 @@ namespace internal { // that it knows how to process. The summary of stability of a binder is // represented by a Stability::Category object. // WARNING: These 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 class Stability final { public: // 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); // 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 // WARNING: This is only ever expected to be called by auto-generated code. You likely want to // change or modify the stability class of the interface you are using. // This must be called as soon as the binder in question is constructed. No thread safety Loading Loading @@ -139,9 +146,14 @@ private: // returns the stability according to how this was built static Level getLocalLevel(); enum { REPR_NONE = 0, REPR_LOG = 1, REPR_ALLOW_DOWNGRADE = 2, }; // applies stability to binder if stability level is known __attribute__((warn_unused_result)) static status_t setRepr(IBinder* binder, int32_t representation, bool log); static status_t setRepr(IBinder* binder, int32_t representation, uint32_t flags); // get stability information as encoded on the wire static Category getCategory(IBinder* binder); Loading
libs/binder/tests/binderStabilityTest.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,17 @@ TEST(BinderStability, OnlyVintfStabilityBinderNeedsVintfDeclaration) { EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf())); } TEST(BinderStability, ForceDowngradeStability) { 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 Stability::forceDowngradeCompilationUnit(someBinder); EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder)); } TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) { sp<IBinder> vintfServer = BadStableBinder::vintf(); Loading