blob: ca927272f8f62f867a05634d683e060b26ad6190 [file] [log] [blame]
Steven Moreland2e87adc2018-08-20 19:47:00 -07001/*
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_manager.h>
19#include <iface/iface.h>
20
Steven Moreland507547f2018-11-06 15:58:05 -080021#include <android/binder_auto_utils.h>
22
Steven Moreland2e87adc2018-08-20 19:47:00 -070023using ::android::sp;
24using ::android::wp;
25
26const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
Steven Moreland507547f2018-11-06 15:58:05 -080027const char* IFoo::kInstanceNameToDieFor = "libbinder_ndk-test-IFoo-to-die";
Devin Moore9f9d0e12024-02-29 22:07:12 +000028const char* IFoo::kInstanceNameToDieFor2 = "libbinder_ndk-test-IFoo-to-die2";
Stephen Crane8fde87f2020-11-17 15:06:11 -080029const char* IFoo::kIFooDescriptor = "my-special-IFoo-class";
Steven Moreland2e87adc2018-08-20 19:47:00 -070030
31struct IFoo_Class_Data {
32 sp<IFoo> foo;
33};
34
35void* IFoo_Class_onCreate(void* args) {
36 IFoo_Class_Data* foo = static_cast<IFoo_Class_Data*>(args);
37 // This is a foo, but we're currently not verifying that. So, the method newLocalBinder is
38 // coupled with this.
39 return static_cast<void*>(foo);
40}
41
42void IFoo_Class_onDestroy(void* userData) {
43 delete static_cast<IFoo_Class_Data*>(userData);
44}
45
46binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in,
47 AParcel* out) {
Steven Moreland5d62e442018-09-13 15:01:02 -070048 binder_status_t stat = STATUS_FAILED_TRANSACTION;
Steven Moreland2e87adc2018-08-20 19:47:00 -070049
50 sp<IFoo> foo = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder))->foo;
51 CHECK(foo != nullptr) << "Transaction made on already deleted object";
52
53 switch (code) {
54 case IFoo::DOFOO: {
55 int32_t valueIn;
Steven Moreland507547f2018-11-06 15:58:05 -080056 int32_t valueOut;
Steven Moreland2e87adc2018-08-20 19:47:00 -070057 stat = AParcel_readInt32(in, &valueIn);
Steven Moreland5d62e442018-09-13 15:01:02 -070058 if (stat != STATUS_OK) break;
Steven Moreland507547f2018-11-06 15:58:05 -080059 stat = foo->doubleNumber(valueIn, &valueOut);
60 if (stat != STATUS_OK) break;
Steven Moreland2e87adc2018-08-20 19:47:00 -070061 stat = AParcel_writeInt32(out, valueOut);
62 break;
63 }
Steven Moreland507547f2018-11-06 15:58:05 -080064 case IFoo::DIE: {
65 stat = foo->die();
66 break;
67 }
Steven Moreland2e87adc2018-08-20 19:47:00 -070068 }
69
70 return stat;
71}
72
73AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate,
74 IFoo_Class_onDestroy, IFoo_Class_onTransact);
75
Steven Morelandfaf25a42022-12-21 02:21:36 +000076// Defines the same class. Ordinarly, you would never want to do this, but it's done here
77// to simulate what would happen when multiple linker namespaces interact.
78AIBinder_Class* IFoo::kClassDupe = AIBinder_Class_define(
79 kIFooDescriptor, IFoo_Class_onCreate, IFoo_Class_onDestroy, IFoo_Class_onTransact);
80
Steven Moreland2e87adc2018-08-20 19:47:00 -070081class BpFoo : public IFoo {
Steven Moreland6cf66ac2018-11-02 18:14:54 -070082 public:
Chih-Hung Hsieh5ca1ea42018-12-20 15:42:22 -080083 explicit BpFoo(AIBinder* binder) : mBinder(binder) {}
Steven Moreland2e87adc2018-08-20 19:47:00 -070084 virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
85
Steven Moreland507547f2018-11-06 15:58:05 -080086 virtual binder_status_t doubleNumber(int32_t in, int32_t* out) {
87 binder_status_t stat = STATUS_OK;
88
Steven Moreland2e87adc2018-08-20 19:47:00 -070089 AParcel* parcelIn;
Steven Moreland507547f2018-11-06 15:58:05 -080090 stat = AIBinder_prepareTransaction(mBinder, &parcelIn);
91 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070092
Steven Moreland507547f2018-11-06 15:58:05 -080093 stat = AParcel_writeInt32(parcelIn, in);
94 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070095
Steven Moreland507547f2018-11-06 15:58:05 -080096 ::ndk::ScopedAParcel parcelOut;
97 stat = AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, parcelOut.getR(), 0 /*flags*/);
98 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070099
Steven Moreland507547f2018-11-06 15:58:05 -0800100 stat = AParcel_readInt32(parcelOut.get(), out);
101 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -0700102
Steven Moreland507547f2018-11-06 15:58:05 -0800103 return stat;
104 }
Steven Morelandcaa776c2018-09-04 13:48:11 -0700105
Steven Moreland507547f2018-11-06 15:58:05 -0800106 virtual binder_status_t die() {
107 binder_status_t stat = STATUS_OK;
108
109 AParcel* parcelIn;
110 stat = AIBinder_prepareTransaction(mBinder, &parcelIn);
111
112 ::ndk::ScopedAParcel parcelOut;
113 stat = AIBinder_transact(mBinder, IFoo::DIE, &parcelIn, parcelOut.getR(), 0 /*flags*/);
114
115 return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -0700116 }
117
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700118 private:
Steven Moreland2e87adc2018-08-20 19:47:00 -0700119 // Always assumes one refcount
120 AIBinder* mBinder;
121};
122
123IFoo::~IFoo() {
Steven Moreland9b80e282018-09-19 13:57:23 -0700124 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700125}
126
Steven Moreland88234072020-08-06 19:32:45 +0000127AIBinder* IFoo::getBinder() {
Steven Moreland2e87adc2018-08-20 19:47:00 -0700128 AIBinder* binder = nullptr;
129
130 if (mWeakBinder != nullptr) {
131 // one strong ref count of binder
132 binder = AIBinder_Weak_promote(mWeakBinder);
133 }
134 if (binder == nullptr) {
135 // or one strong refcount here
136 binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
137 if (mWeakBinder != nullptr) {
Steven Moreland9b80e282018-09-19 13:57:23 -0700138 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700139 }
140 mWeakBinder = AIBinder_Weak_new(binder);
Steven Moreland88234072020-08-06 19:32:45 +0000141
142 // WARNING: it is important that this class does not implement debug or
143 // shell functions because it does not use special C++ wrapper
144 // functions, and so this is how we test those functions.
Steven Moreland2e87adc2018-08-20 19:47:00 -0700145 }
146
Steven Moreland88234072020-08-06 19:32:45 +0000147 return binder;
148}
149
150binder_status_t IFoo::addService(const char* instance) {
151 AIBinder* binder = getBinder();
152
Steven Moreland2e87adc2018-08-20 19:47:00 -0700153 binder_status_t status = AServiceManager_addService(binder, instance);
154 // Strong references we care about kept by remote process
155 AIBinder_decStrong(binder);
156 return status;
157}
158
Steven Moreland507547f2018-11-06 15:58:05 -0800159sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) {
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000160#pragma clang diagnostic push
161#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700162 AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
Tomasz Wasilczykbb07b982023-10-11 21:25:36 +0000163#pragma clang diagnostic pop
Steven Moreland2e87adc2018-08-20 19:47:00 -0700164 if (binder == nullptr) {
165 return nullptr;
166 }
167
Steven Moreland71cddc32018-08-30 23:39:22 -0700168 if (!AIBinder_associateClass(binder, IFoo::kClass)) {
169 AIBinder_decStrong(binder);
170 return nullptr;
171 }
172
Steven Moreland507547f2018-11-06 15:58:05 -0800173 if (outBinder != nullptr) {
174 AIBinder_incStrong(binder);
175 *outBinder = binder;
176 }
177
Steven Moreland2e87adc2018-08-20 19:47:00 -0700178 if (AIBinder_isRemote(binder)) {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700179 sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder
Steven Moreland2e87adc2018-08-20 19:47:00 -0700180 return ret;
181 }
182
183 IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder));
184
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700185 CHECK(data != nullptr); // always created with non-null data
Steven Moreland2e87adc2018-08-20 19:47:00 -0700186
187 sp<IFoo> ret = data->foo;
188
189 AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder);
190 CHECK(held == binder);
191 AIBinder_decStrong(held);
192
Steven Moreland2e87adc2018-08-20 19:47:00 -0700193 AIBinder_decStrong(binder);
194 return ret;
195}