1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android-base/logging.h>
18 #include <android/binder_ibinder_jni.h>
19 #include <android/binder_manager.h>
20 #include <android/binder_process.h>
21 #include <gtest/gtest.h>
22 #include <iface/iface.h>
23
24 #include <chrono>
25 #include <condition_variable>
26 #include <mutex>
27
28 using ::android::sp;
29
30 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
31
32 // This is too slow
33 // TEST(NdkBinder, GetServiceThatDoesntExist) {
34 // sp<IFoo> foo = IFoo::getService("asdfghkl;");
35 // EXPECT_EQ(nullptr, foo.get());
36 // }
37
TEST(NdkBinder,CheckServiceThatDoesntExist)38 TEST(NdkBinder, CheckServiceThatDoesntExist) {
39 AIBinder* binder = AServiceManager_checkService("asdfghkl;");
40 ASSERT_EQ(nullptr, binder);
41 }
42
TEST(NdkBinder,CheckServiceThatDoesExist)43 TEST(NdkBinder, CheckServiceThatDoesExist) {
44 AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
45 EXPECT_NE(nullptr, binder);
46 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
47
48 AIBinder_decStrong(binder);
49 }
50
TEST(NdkBinder,DoubleNumber)51 TEST(NdkBinder, DoubleNumber) {
52 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
53 ASSERT_NE(foo, nullptr);
54
55 int32_t out;
56 EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
57 EXPECT_EQ(2, out);
58 }
59
LambdaOnDeath(void * cookie)60 void LambdaOnDeath(void* cookie) {
61 auto onDeath = static_cast<std::function<void(void)>*>(cookie);
62 (*onDeath)();
63 };
TEST(NdkBinder,DeathRecipient)64 TEST(NdkBinder, DeathRecipient) {
65 using namespace std::chrono_literals;
66
67 AIBinder* binder;
68 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
69 ASSERT_NE(nullptr, foo.get());
70 ASSERT_NE(nullptr, binder);
71
72 std::mutex deathMutex;
73 std::condition_variable deathCv;
74 bool deathRecieved = false;
75
76 std::function<void(void)> onDeath = [&] {
77 std::cerr << "Binder died (as requested)." << std::endl;
78 deathRecieved = true;
79 deathCv.notify_one();
80 };
81
82 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
83
84 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
85
86 // the binder driver should return this if the service dies during the transaction
87 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
88
89 foo = nullptr;
90 AIBinder_decStrong(binder);
91 binder = nullptr;
92
93 std::unique_lock<std::mutex> lock(deathMutex);
94 EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
95 EXPECT_TRUE(deathRecieved);
96
97 AIBinder_DeathRecipient_delete(recipient);
98 }
99
TEST(NdkBinder,RetrieveNonNdkService)100 TEST(NdkBinder, RetrieveNonNdkService) {
101 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
102 ASSERT_NE(nullptr, binder);
103 EXPECT_TRUE(AIBinder_isRemote(binder));
104 EXPECT_TRUE(AIBinder_isAlive(binder));
105 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
106
107 AIBinder_decStrong(binder);
108 }
109
OnBinderDeath(void * cookie)110 void OnBinderDeath(void* cookie) {
111 LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
112 }
113
TEST(NdkBinder,LinkToDeath)114 TEST(NdkBinder, LinkToDeath) {
115 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
116 ASSERT_NE(nullptr, binder);
117
118 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
119 ASSERT_NE(nullptr, recipient);
120
121 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
122 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
123 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
124 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
125 EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
126
127 AIBinder_DeathRecipient_delete(recipient);
128 AIBinder_decStrong(binder);
129 }
130
131 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)132 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
133 *out = 2 * in;
134 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
135 return STATUS_OK;
136 }
die()137 binder_status_t die() override {
138 ADD_FAILURE() << "die called on local instance";
139 return STATUS_OK;
140 }
141 };
142
TEST(NdkBinder,GetServiceInProcess)143 TEST(NdkBinder, GetServiceInProcess) {
144 static const char* kInstanceName = "test-get-service-in-process";
145
146 sp<IFoo> foo = new MyTestFoo;
147 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName));
148
149 sp<IFoo> getFoo = IFoo::getService(kInstanceName);
150 EXPECT_EQ(foo.get(), getFoo.get());
151
152 int32_t out;
153 EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
154 EXPECT_EQ(2, out);
155 }
156
TEST(NdkBinder,EqualityOfRemoteBinderPointer)157 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
158 AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
159 ASSERT_NE(nullptr, binderA);
160
161 AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
162 ASSERT_NE(nullptr, binderB);
163
164 EXPECT_EQ(binderA, binderB);
165
166 AIBinder_decStrong(binderA);
167 AIBinder_decStrong(binderB);
168 }
169
TEST(NdkBinder,ToFromJavaNullptr)170 TEST(NdkBinder, ToFromJavaNullptr) {
171 EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
172 EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
173 }
174
TEST(NdkBinder,ABpBinderRefCount)175 TEST(NdkBinder, ABpBinderRefCount) {
176 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
177 AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
178
179 ASSERT_NE(nullptr, binder);
180 EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
181
182 AIBinder_decStrong(binder);
183
184 // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
185 ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
186
187 AIBinder_Weak_delete(wBinder);
188 }
189
TEST(NdkBinder,AddServiceMultipleTimes)190 TEST(NdkBinder, AddServiceMultipleTimes) {
191 static const char* kInstanceName1 = "test-multi-1";
192 static const char* kInstanceName2 = "test-multi-2";
193 sp<IFoo> foo = new MyTestFoo;
194 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName1));
195 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
196 EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
197 }
198
main(int argc,char * argv[])199 int main(int argc, char* argv[]) {
200 ::testing::InitGoogleTest(&argc, argv);
201
202 ABinderProcess_setThreadPoolMaxThreadCount(1); // to recieve death notifications/callbacks
203 ABinderProcess_startThreadPool();
204
205 return RUN_ALL_TESTS();
206 }
207
208 #include <android/binder_auto_utils.h>
209 #include <android/binder_interface_utils.h>
210 #include <android/binder_parcel_utils.h>
211