libbinder_ndk: stability settings
Allow apex/vendor users to set stability.
Bug: 136027762
Test: binderStabilityTest
Test: manually creating a vendor service and
checking for expected behavior
Change-Id: Icbf8b2fdb8af00a64fcbf7a1c2c29e640ac9da29
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 6da3086..1beacdf 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -33,6 +33,7 @@
"ibinder_jni.cpp",
"parcel.cpp",
"process.cpp",
+ "stability.cpp",
"status.cpp",
"service_manager.cpp",
],
@@ -54,7 +55,7 @@
version_script: "libbinder_ndk.map.txt",
stubs: {
symbol_file: "libbinder_ndk.map.txt",
- versions: ["29"],
+ versions: ["29", "30"],
},
}
diff --git a/libs/binder/ndk/include_apex/android/binder_stability.h b/libs/binder/ndk/include_apex/android/binder_stability.h
new file mode 100644
index 0000000..e6aeb04
--- /dev/null
+++ b/libs/binder/ndk/include_apex/android/binder_stability.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+
+__BEGIN_DECLS
+
+#ifdef __ANDROID_VNDK__
+
+/**
+ * This interface has the stability of the vendor image.
+ */
+void AIBinder_markVendorStability(AIBinder* binder);
+
+static inline void AIBinder_markCompilationUnitStability(AIBinder* binder) {
+ AIBinder_markVendorStability(binder);
+}
+
+#else // ndef defined __ANDROID_VNDK__
+
+/**
+ * This interface has the stability of the system image.
+ */
+void AIBinder_markSystemStability(AIBinder* binder);
+
+static inline void AIBinder_markCompilationUnitStability(AIBinder* binder) {
+ AIBinder_markSystemStability(binder);
+}
+
+#endif // ifdef __ANDROID_VNDK__
+
+/**
+ * This interface has system<->vendor stability
+ */
+void AIBinder_markVintfStability(AIBinder* binder);
+
+__END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 4f685d1..feedde6 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -98,3 +98,12 @@
local:
*;
};
+
+LIBBINDER_NDK30 { # introduced=30
+ global:
+ AIBinder_markSystemStability; # apex
+ AIBinder_markVendorStability; # vndk
+ AIBinder_markVintfStability; # apex vndk
+ local:
+ *;
+};
diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp
new file mode 100644
index 0000000..abafe1f
--- /dev/null
+++ b/libs/binder/ndk/stability.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_stability.h>
+
+#include <binder/Stability.h>
+#include "ibinder_internal.h"
+
+#include <log/log.h>
+
+using ::android::internal::Stability;
+
+#ifdef __ANDROID_VNDK__
+#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());
+}
+
+void AIBinder_markSystemStability(AIBinder* binder) {
+ Stability::markCompilationUnit(binder->getBinder().get());
+}
+
+void AIBinder_markVintfStability(AIBinder* binder) {
+ Stability::markVintf(binder->getBinder().get());
+}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 724cb15..d59a40d 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -138,18 +138,31 @@
test_suites: ["device-tests"],
}
+aidl_interface {
+ name: "binderStabilityTestIface",
+ srcs: [
+ "IBinderStabilityTest.aidl",
+ "IBinderStabilityTestSub.aidl",
+ ],
+}
+
cc_test {
name: "binderStabilityTest",
defaults: ["binder_test_defaults"],
srcs: [
"binderStabilityTest.cpp",
- "IBinderStabilityTest.aidl",
- "IBinderStabilityTestSub.aidl",
],
shared_libs: [
+ "libbinder_ndk",
"libbinder",
+ "liblog",
"libutils",
],
+ static_libs: [
+ "binderStabilityTestIface-cpp",
+ "binderStabilityTestIface-ndk_platform",
+ ],
+
test_suites: ["device-tests"],
}
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 52595e0..936b821 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <android/binder_manager.h>
+#include <android/binder_stability.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
@@ -24,47 +26,53 @@
#include <sys/prctl.h>
+#include "aidl/BnBinderStabilityTestSub.h"
+#include "aidl/BnBinderStabilityTest.h"
#include "BnBinderStabilityTestSub.h"
#include "BnBinderStabilityTest.h"
-#include "BpBinderStabilityTest.h"
using namespace android;
+using namespace ndk;
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 kCompilationUnitNdkServer = String16("binder_stability_test_service_compl");
+
class BadStabilityTestSub : public BnBinderStabilityTestSub {
+public:
Status userDefinedTransaction() {
return Status::ok();
}
+
+ 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
+ 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
+ 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
+ return iface;
+ }
};
-sp<IBinderStabilityTestSub> getCompilationUnitStability() {
- sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
- // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
- // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
- internal::Stability::markCompilationUnit(iface.get()); // <- BAD, NO! DO NOT COPY
- return iface;
-}
-
-sp<IBinderStabilityTestSub> getVintfStability() {
- sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
- // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
- // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
- internal::Stability::markVintf(iface.get()); // <- BAD, NO! DO NOT COPY
- return iface;
-}
-
-sp<IBinderStabilityTestSub> getVendorStability() {
- sp<BnBinderStabilityTestSub> iface = new BadStabilityTestSub();
- // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS?
- // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS
- internal::Stability::markVndk(iface.get()); // <- BAD, NO! DO NOT COPY
- return iface;
-}
-
// 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!
@@ -74,6 +82,7 @@
return Status::ok();
}
Status sendAndCallBinder(const sp<IBinderStabilityTestSub>& binder) override {
+ Stability::debugLogStability("sendAndCallBinder got binder", IInterface::asBinder(binder));
return binder->userDefinedTransaction();
}
Status returnNoStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
@@ -81,31 +90,31 @@
return Status::ok();
}
Status returnLocalStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
- *_aidl_return = getCompilationUnitStability();
+ *_aidl_return = BadStabilityTestSub::system();
return Status::ok();
}
Status returnVintfStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
- *_aidl_return = getVintfStability();
+ *_aidl_return = BadStabilityTestSub::vintf();
return Status::ok();
}
Status returnVendorStabilityBinder(sp<IBinderStabilityTestSub>* _aidl_return) override {
- *_aidl_return = getVendorStability();
+ *_aidl_return = BadStabilityTestSub::vendor();
return Status::ok();
}
};
void checkSystemStabilityBinder(const sp<IBinderStabilityTest>& complServer) {
EXPECT_TRUE(complServer->sendBinder(new BadStabilityTestSub()).isOk());
- EXPECT_TRUE(complServer->sendBinder(getCompilationUnitStability()).isOk());
- EXPECT_TRUE(complServer->sendBinder(getVintfStability()).isOk());
- EXPECT_TRUE(complServer->sendBinder(getVendorStability()).isOk());
+ EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::system()).isOk());
+ EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::vintf()).isOk());
+ EXPECT_TRUE(complServer->sendBinder(BadStabilityTestSub::vendor()).isOk());
EXPECT_TRUE(complServer->sendAndCallBinder(new BadStabilityTestSub()).isOk());
- EXPECT_TRUE(complServer->sendAndCallBinder(getCompilationUnitStability()).isOk());
- EXPECT_TRUE(complServer->sendAndCallBinder(getVintfStability()).isOk());
+ EXPECT_TRUE(complServer->sendAndCallBinder(BadStabilityTestSub::system()).isOk());
+ EXPECT_TRUE(complServer->sendAndCallBinder(BadStabilityTestSub::vintf()).isOk());
// !!! user-defined transaction may not be stable for remote server !!!
- EXPECT_FALSE(complServer->sendAndCallBinder(getVendorStability()).isOk());
+ EXPECT_FALSE(complServer->sendAndCallBinder(BadStabilityTestSub::vendor()).isOk());
sp<IBinderStabilityTestSub> out;
EXPECT_TRUE(complServer->returnNoStabilityBinder(&out).isOk());
@@ -163,12 +172,39 @@
checkSystemStabilityBinder(remoteServer);
}
+class NdkBadStabilityTestSub : public aidl::BnBinderStabilityTestSub {
+ ScopedAStatus userDefinedTransaction() {
+ return ScopedAStatus::ok();
+ }
+};
+// for testing only to get around __ANDROID_VNDK__ guard.
+extern "C" void AIBinder_markVendorStability(AIBinder* binder); // <- BAD DO NOT COPY
+
+TEST(BinderStability, NdkClientOfRemoteServer) {
+ SpAIBinder binder = SpAIBinder(AServiceManager_getService(
+ String8(kCompilationUnitServer).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>();
+
+ // TODO: not ideal: binder must be held once it is marked
+ SpAIBinder vendorBinder = vendor->asBinder();
+ AIBinder_markVendorStability(vendorBinder.get());
+
+ EXPECT_TRUE(remoteServer->sendBinder(vendor).isOk());
+ EXPECT_FALSE(remoteServer->sendAndCallBinder(vendor).isOk());
+}
+
class MarksStabilityInConstructor : public BBinder {
public:
static bool gDestructed;
MarksStabilityInConstructor() {
- internal::Stability::markCompilationUnit(this);
+ Stability::markCompilationUnit(this);
}
~MarksStabilityInConstructor() {
gDestructed = true;
@@ -202,11 +238,11 @@
android::defaultServiceManager()->addService(kNoStabilityServer, noStability);
sp<IBinder> compil = new BadStabilityTester;
- internal::Stability::markCompilationUnit(compil.get());
+ Stability::markCompilationUnit(compil.get());
android::defaultServiceManager()->addService(kCompilationUnitServer, compil);
sp<IBinder> vintf = new BadStabilityTester;
- internal::Stability::markVintf(vintf.get());
+ Stability::markVintf(vintf.get());
android::defaultServiceManager()->addService(kVintfServer, vintf);
IPCThreadState::self()->joinThreadPool(true);