Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2017343 authored by Steven Moreland's avatar Steven Moreland
Browse files

Test double-loading libbinder.

This is in preparation for the technical possibility of vendor using
libbinder_ndk to communicate w/ Stable AIDL interfaces on system or for
other possible usecases which may use double loaded libbinder.

Bug: 136027762
Bug: 138450837
Test: atest binderVendorDoubleLoadTest
Change-Id: I7b166ae08954283b378e1f18d2c44dcf70e698c5
parent 1ed80f45
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3,6 +3,9 @@
    {
      "name": "binderSafeInterfaceTest"
    },
    {
      "name": "binderVendorDoubleLoadTest"
    },
    {
      "name": "binderDriverInterfaceTest"
    },
+28 −0
Original line number Diff line number Diff line
@@ -67,3 +67,31 @@ cc_test {
    srcs: ["main_server.cpp"],
    gtest: false,
}

cc_test {
    name: "binderVendorDoubleLoadTest",
    vendor: true,
    srcs: [
        "binderVendorDoubleLoadTest.cpp",
    ],
    static_libs: [
        "IBinderVendorDoubleLoadTest-cpp",
        "IBinderVendorDoubleLoadTest-ndk_platform",
    ],
    shared_libs: [
        "libbase",
        "libbinder",
        "libbinder_ndk",
        "libutils",
    ],
    test_suites: ["device-tests"],
}

aidl_interface {
    name: "IBinderVendorDoubleLoadTest",
    // TODO(b/119771576): only vendor is needed
    vendor_available: true,
    srcs: [
        "IBinderVendorDoubleLoadTest.aidl",
    ],
}
+32 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<configuration description="Runs binderVendorDoubleLoadTest.">
    <option name="test-suite-tag" value="apct" />
    <option name="test-suite-tag" value="apct-native" />

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>

    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
        <option name="cleanup" value="true" />
        <option name="push" value="binderVendorDoubleLoadTest->/data/nativetest/vendor/binderVendorDoubleLoadTest" />
    </target_preparer>

    <test class="com.android.tradefed.testtype.GTest" >
        <option name="native-test-device-path" value="/data/nativetest/vendor" />
        <option name="module-name" value="binderVendorDoubleLoadTest" />
    </test>
</configuration>
+19 −0
Original line number Diff line number Diff line
/*
 * 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 IBinderVendorDoubleLoadTest {
    @utf8InCpp String RepeatString(@utf8InCpp String toRepeat);
}
+149 −0
Original line number Diff line number Diff line
/*
 * 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 <BnBinderVendorDoubleLoadTest.h>
#include <aidl/BnBinderVendorDoubleLoadTest.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/binder_stability.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Stability.h>
#include <binder/Status.h>
#include <gtest/gtest.h>

#include <sys/prctl.h>

using namespace android;
using ::android::base::EndsWith;
using ::android::base::GetProperty;
using ::android::base::Split;
using ::android::binder::Status;
using ::android::internal::Stability;
using ::ndk::ScopedAStatus;
using ::ndk::SharedRefBase;
using ::ndk::SpAIBinder;

static const std::string kLocalNdkServerName = "NdkServer-local-IBinderVendorDoubleLoadTest";
static const std::string kRemoteNdkServerName = "NdkServer-remote-IBinderVendorDoubleLoadTest";

class NdkServer : public aidl::BnBinderVendorDoubleLoadTest {
    ScopedAStatus RepeatString(const std::string& in, std::string* out) override {
        *out = in;
        return ScopedAStatus::ok();
    }
};
class CppServer : public BnBinderVendorDoubleLoadTest {
    Status RepeatString(const std::string& in, std::string* out) override {
        *out = in;
        return Status::ok();
    }
};

TEST(DoubleBinder, VendorCppCantCallIntoSystem) {
    Vector<String16> services = defaultServiceManager()->listServices();
    EXPECT_TRUE(services.empty());
}

TEST(DoubleBinder, VendorCppCantRegisterService) {
    sp<CppServer> cppServer = new CppServer;
    status_t status = defaultServiceManager()->addService(String16("anything"), cppServer);
    EXPECT_EQ(EX_TRANSACTION_FAILED, status);
}

TEST(DoubleBinder, CppVendorCantManuallyMarkVintfStability) {
    // this test also implies that stability logic is turned on in vendor
    ASSERT_DEATH(
            {
                sp<IBinder> binder = new CppServer();
                Stability::markVintf(binder.get());
            },
            "Should only mark known object.");
}

TEST(DoubleBinder, NdkVendorCantManuallyMarkVintfStability) {
    // this test also implies that stability logic is turned on in vendor
    ASSERT_DEATH(
            {
                std::shared_ptr<NdkServer> ndkServer = SharedRefBase::make<NdkServer>();
                AIBinder_markVintfStability(ndkServer->asBinder().get());
            },
            "Should only mark known object.");
}

TEST(DoubleBinder, CallIntoNdk) {
    for (const std::string& serviceName : {kLocalNdkServerName, kRemoteNdkServerName}) {
        SpAIBinder binder = SpAIBinder(AServiceManager_checkService(serviceName.c_str()));
        ASSERT_NE(nullptr, binder.get()) << serviceName;
        EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get())) << serviceName;

        std::shared_ptr<aidl::IBinderVendorDoubleLoadTest> server =
                aidl::IBinderVendorDoubleLoadTest::fromBinder(binder);

        ASSERT_NE(nullptr, server.get()) << serviceName;

        EXPECT_EQ(STATUS_OK, AIBinder_ping(server->asBinder().get()));

        std::string outString;
        ScopedAStatus status = server->RepeatString("foo", &outString);
        EXPECT_EQ(STATUS_OK, AStatus_getExceptionCode(status.get())) << serviceName;
        EXPECT_EQ("foo", outString) << serviceName;
    }
}

void initDrivers() {
    // Explicitly instantiated with the same driver that system would use.
    // __ANDROID_VNDK__ right now uses /dev/vndbinder by default.
    ProcessState::initWithDriver("/dev/binder");
    ProcessState::self()->startThreadPool();
    ABinderProcess_startThreadPool();
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);

    if (fork() == 0) {
        // child process

        prctl(PR_SET_PDEATHSIG, SIGHUP);

        initDrivers();

        // REMOTE SERVERS
        std::shared_ptr<NdkServer> ndkServer = SharedRefBase::make<NdkServer>();
        CHECK(STATUS_OK == AServiceManager_addService(ndkServer->asBinder().get(),
                                                      kRemoteNdkServerName.c_str()));

        // OR sleep forever or whatever, it doesn't matter
        IPCThreadState::self()->joinThreadPool(true);
        exit(1);  // should not reach
    }

    sleep(1);

    initDrivers();

    // LOCAL SERVERS
    std::shared_ptr<NdkServer> ndkServer = SharedRefBase::make<NdkServer>();
    AServiceManager_addService(ndkServer->asBinder().get(), kLocalNdkServerName.c_str());

    return RUN_ALL_TESTS();
}