blob: 6ef964e8961e89de899823631cf5aff860c67b76 [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";
Steven Moreland2e87adc2018-08-20 19:47:00 -070028const char* kIFooDescriptor = "my-special-IFoo-class";
29
30struct IFoo_Class_Data {
31 sp<IFoo> foo;
32};
33
34void* IFoo_Class_onCreate(void* args) {
35 IFoo_Class_Data* foo = static_cast<IFoo_Class_Data*>(args);
36 // This is a foo, but we're currently not verifying that. So, the method newLocalBinder is
37 // coupled with this.
38 return static_cast<void*>(foo);
39}
40
41void IFoo_Class_onDestroy(void* userData) {
42 delete static_cast<IFoo_Class_Data*>(userData);
43}
44
45binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in,
46 AParcel* out) {
Steven Moreland5d62e442018-09-13 15:01:02 -070047 binder_status_t stat = STATUS_FAILED_TRANSACTION;
Steven Moreland2e87adc2018-08-20 19:47:00 -070048
49 sp<IFoo> foo = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder))->foo;
50 CHECK(foo != nullptr) << "Transaction made on already deleted object";
51
52 switch (code) {
53 case IFoo::DOFOO: {
54 int32_t valueIn;
Steven Moreland507547f2018-11-06 15:58:05 -080055 int32_t valueOut;
Steven Moreland2e87adc2018-08-20 19:47:00 -070056 stat = AParcel_readInt32(in, &valueIn);
Steven Moreland5d62e442018-09-13 15:01:02 -070057 if (stat != STATUS_OK) break;
Steven Moreland507547f2018-11-06 15:58:05 -080058 stat = foo->doubleNumber(valueIn, &valueOut);
59 if (stat != STATUS_OK) break;
Steven Moreland2e87adc2018-08-20 19:47:00 -070060 stat = AParcel_writeInt32(out, valueOut);
61 break;
62 }
Steven Moreland507547f2018-11-06 15:58:05 -080063 case IFoo::DIE: {
64 stat = foo->die();
65 break;
66 }
Steven Moreland2e87adc2018-08-20 19:47:00 -070067 }
68
69 return stat;
70}
71
72AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate,
73 IFoo_Class_onDestroy, IFoo_Class_onTransact);
74
75class BpFoo : public IFoo {
Steven Moreland6cf66ac2018-11-02 18:14:54 -070076 public:
Steven Moreland2e87adc2018-08-20 19:47:00 -070077 BpFoo(AIBinder* binder) : mBinder(binder) {}
78 virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
79
Steven Moreland507547f2018-11-06 15:58:05 -080080 virtual binder_status_t doubleNumber(int32_t in, int32_t* out) {
81 binder_status_t stat = STATUS_OK;
82
Steven Moreland2e87adc2018-08-20 19:47:00 -070083 AParcel* parcelIn;
Steven Moreland507547f2018-11-06 15:58:05 -080084 stat = AIBinder_prepareTransaction(mBinder, &parcelIn);
85 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070086
Steven Moreland507547f2018-11-06 15:58:05 -080087 stat = AParcel_writeInt32(parcelIn, in);
88 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070089
Steven Moreland507547f2018-11-06 15:58:05 -080090 ::ndk::ScopedAParcel parcelOut;
91 stat = AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, parcelOut.getR(), 0 /*flags*/);
92 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070093
Steven Moreland507547f2018-11-06 15:58:05 -080094 stat = AParcel_readInt32(parcelOut.get(), out);
95 if (stat != STATUS_OK) return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -070096
Steven Moreland507547f2018-11-06 15:58:05 -080097 return stat;
98 }
Steven Morelandcaa776c2018-09-04 13:48:11 -070099
Steven Moreland507547f2018-11-06 15:58:05 -0800100 virtual binder_status_t die() {
101 binder_status_t stat = STATUS_OK;
102
103 AParcel* parcelIn;
104 stat = AIBinder_prepareTransaction(mBinder, &parcelIn);
105
106 ::ndk::ScopedAParcel parcelOut;
107 stat = AIBinder_transact(mBinder, IFoo::DIE, &parcelIn, parcelOut.getR(), 0 /*flags*/);
108
109 return stat;
Steven Moreland2e87adc2018-08-20 19:47:00 -0700110 }
111
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700112 private:
Steven Moreland2e87adc2018-08-20 19:47:00 -0700113 // Always assumes one refcount
114 AIBinder* mBinder;
115};
116
117IFoo::~IFoo() {
Steven Moreland9b80e282018-09-19 13:57:23 -0700118 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700119}
120
121binder_status_t IFoo::addService(const char* instance) {
122 AIBinder* binder = nullptr;
123
124 if (mWeakBinder != nullptr) {
125 // one strong ref count of binder
126 binder = AIBinder_Weak_promote(mWeakBinder);
127 }
128 if (binder == nullptr) {
129 // or one strong refcount here
130 binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
131 if (mWeakBinder != nullptr) {
Steven Moreland9b80e282018-09-19 13:57:23 -0700132 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700133 }
134 mWeakBinder = AIBinder_Weak_new(binder);
135 }
136
137 binder_status_t status = AServiceManager_addService(binder, instance);
138 // Strong references we care about kept by remote process
139 AIBinder_decStrong(binder);
140 return status;
141}
142
Steven Moreland507547f2018-11-06 15:58:05 -0800143sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700144 AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
Steven Moreland2e87adc2018-08-20 19:47:00 -0700145 if (binder == nullptr) {
146 return nullptr;
147 }
148
Steven Moreland71cddc32018-08-30 23:39:22 -0700149 if (!AIBinder_associateClass(binder, IFoo::kClass)) {
150 AIBinder_decStrong(binder);
151 return nullptr;
152 }
153
Steven Moreland507547f2018-11-06 15:58:05 -0800154 if (outBinder != nullptr) {
155 AIBinder_incStrong(binder);
156 *outBinder = binder;
157 }
158
Steven Moreland2e87adc2018-08-20 19:47:00 -0700159 if (AIBinder_isRemote(binder)) {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700160 sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder
Steven Moreland2e87adc2018-08-20 19:47:00 -0700161 return ret;
162 }
163
164 IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder));
165
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700166 CHECK(data != nullptr); // always created with non-null data
Steven Moreland2e87adc2018-08-20 19:47:00 -0700167
168 sp<IFoo> ret = data->foo;
169
170 AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder);
171 CHECK(held == binder);
172 AIBinder_decStrong(held);
173
Steven Moreland2e87adc2018-08-20 19:47:00 -0700174 AIBinder_decStrong(binder);
175 return ret;
176}