| /* |
| * Copyright (C) 2018 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. |
| */ |
| #define LOG_TAG "Cts-NdkBinderTest" |
| |
| #include <android/binder_ibinder_jni.h> |
| #include <gtest/gtest.h> |
| #include <test_package/BnEmpty.h> |
| #include <test_package/BpTest.h> |
| #include <test_package/RegularPolygon.h> |
| |
| #include "itest_impl.h" |
| #include "utilities.h" |
| |
| using ::aidl::test_package::BpTest; |
| using ::aidl::test_package::ITest; |
| using ::aidl::test_package::RegularPolygon; |
| using ::ndk::ScopedAStatus; |
| using ::ndk::SharedRefBase; |
| using ::ndk::SpAIBinder; |
| |
| struct Params { |
| std::shared_ptr<ITest> iface; |
| bool shouldBeRemote; |
| }; |
| |
| #define iface GetParam().iface |
| #define shouldBeRemote GetParam().shouldBeRemote |
| |
| class NdkBinderTest_Aidl : public NdkBinderTest, |
| public ::testing::WithParamInterface<Params> {}; |
| |
| TEST_P(NdkBinderTest_Aidl, GotTest) { ASSERT_NE(nullptr, iface); } |
| |
| TEST_P(NdkBinderTest_Aidl, Remoteness) { |
| ASSERT_EQ(shouldBeRemote, iface->isRemote()); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, UseBinder) { |
| ASSERT_EQ(STATUS_OK, AIBinder_ping(iface->asBinder().get())); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, Trivial) { |
| ASSERT_OK(iface->TestVoidReturn()); |
| ASSERT_OK(iface->TestOneway()); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, Constants) { |
| ASSERT_EQ(0, ITest::kZero); |
| ASSERT_EQ(1, ITest::kOne); |
| ASSERT_EQ(0xffffffff, ITest::kOnes); |
| ASSERT_EQ(std::string(""), ITest::kEmpty); |
| ASSERT_EQ(std::string("foo"), ITest::kFoo); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, RepeatPrimitives) { |
| { |
| int32_t out; |
| ASSERT_OK(iface->RepeatInt(3, &out)); |
| EXPECT_EQ(3, out); |
| } |
| |
| { |
| int64_t out; |
| ASSERT_OK(iface->RepeatLong(3, &out)); |
| EXPECT_EQ(3, out); |
| } |
| |
| { |
| float out; |
| ASSERT_OK(iface->RepeatFloat(2.0f, &out)); |
| EXPECT_EQ(2.0f, out); |
| } |
| |
| { |
| double out; |
| ASSERT_OK(iface->RepeatDouble(3.0, &out)); |
| EXPECT_EQ(3.0, out); |
| } |
| |
| { |
| bool out; |
| ASSERT_OK(iface->RepeatBoolean(true, &out)); |
| EXPECT_EQ(true, out); |
| } |
| |
| { |
| char16_t out; |
| ASSERT_OK(iface->RepeatChar(L'@', &out)); |
| EXPECT_EQ(L'@', out); |
| } |
| |
| { |
| int8_t out; |
| ASSERT_OK(iface->RepeatByte(3, &out)); |
| EXPECT_EQ(3, out); |
| } |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, RepeatBinder) { |
| SpAIBinder binder = iface->asBinder(); |
| SpAIBinder ret; |
| |
| ASSERT_OK(iface->RepeatBinder(binder, &ret)); |
| EXPECT_EQ(binder.get(), ret.get()); |
| |
| ASSERT_OK(iface->RepeatBinder(nullptr, &ret)); |
| EXPECT_EQ(nullptr, ret.get()); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, RepeatInterface) { |
| class MyEmpty : public ::aidl::test_package::BnEmpty {}; |
| |
| std::shared_ptr<IEmpty> empty = SharedRefBase::make<MyEmpty>(); |
| |
| std::shared_ptr<IEmpty> ret; |
| ASSERT_OK(iface->RepeatInterface(empty, &ret)); |
| EXPECT_EQ(empty.get(), ret.get()); |
| |
| ASSERT_OK(iface->RepeatInterface(nullptr, &ret)); |
| EXPECT_EQ(nullptr, ret.get()); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, RepeatString) { |
| std::string res; |
| |
| EXPECT_OK(iface->RepeatString("", &res)); |
| EXPECT_EQ("", res); |
| |
| EXPECT_OK(iface->RepeatString("a", &res)); |
| EXPECT_EQ("a", res); |
| |
| EXPECT_OK(iface->RepeatString("say what?", &res)); |
| EXPECT_EQ("say what?", res); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, ParcelableDefaults) { |
| RegularPolygon polygon; |
| |
| EXPECT_EQ("square", polygon.name); |
| EXPECT_EQ(4, polygon.numSides); |
| EXPECT_EQ(1.0f, polygon.sideLength); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, RepeatPolygon) { |
| RegularPolygon defaultPolygon = {"hexagon", 6, 2.0f}; |
| RegularPolygon outputPolygon; |
| ASSERT_OK(iface->RepeatPolygon(defaultPolygon, &outputPolygon)); |
| EXPECT_EQ("hexagon", outputPolygon.name); |
| EXPECT_EQ(defaultPolygon.numSides, outputPolygon.numSides); |
| EXPECT_EQ(defaultPolygon.sideLength, outputPolygon.sideLength); |
| } |
| |
| TEST_P(NdkBinderTest_Aidl, InsAndOuts) { |
| RegularPolygon defaultPolygon; |
| ASSERT_OK(iface->RenamePolygon(&defaultPolygon, "Jerry")); |
| EXPECT_EQ("Jerry", defaultPolygon.name); |
| } |
| |
| std::shared_ptr<ITest> getLocalService() { |
| // BpTest -> AIBinder -> test |
| std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>(); |
| return BpTest::associate(test->asBinder()); |
| } |
| |
| std::shared_ptr<ITest> getNdkBinderTestJavaService(const std::string& method) { |
| JNIEnv* env = GetEnv(); |
| if (env == nullptr) { |
| std::cout << "No environment" << std::endl; |
| return nullptr; |
| } |
| |
| jclass cl = env->FindClass("android/binder/cts/NdkBinderTest"); |
| if (cl == nullptr) { |
| std::cout << "No class" << std::endl; |
| return nullptr; |
| } |
| |
| jmethodID mid = |
| env->GetStaticMethodID(cl, method.c_str(), "()Landroid/os/IBinder;"); |
| if (mid == nullptr) { |
| std::cout << "No method id" << std::endl; |
| return nullptr; |
| } |
| |
| jobject object = env->CallStaticObjectMethod(cl, mid); |
| if (object == nullptr) { |
| std::cout << "Got null service from Java" << std::endl; |
| return nullptr; |
| } |
| |
| SpAIBinder binder = SpAIBinder(AIBinder_fromJavaBinder(env, object)); |
| |
| return BpTest::associate(binder); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(Local, NdkBinderTest_Aidl, |
| ::testing::Values(Params{getLocalService(), |
| false /*shouldBeRemote*/})); |
| INSTANTIATE_TEST_CASE_P(RemoteNative, NdkBinderTest_Aidl, |
| ::testing::Values(Params{getNdkBinderTestJavaService( |
| "getRemoteNativeService"), |
| true /*shouldBeRemote*/})); |
| INSTANTIATE_TEST_CASE_P(RemoteJava, NdkBinderTest_Aidl, |
| ::testing::Values(Params{ |
| getNdkBinderTestJavaService("getRemoteJavaService"), |
| true /*shouldBeRemote*/})); |