blob: d46fde82e3a3d5cc9fc4e09a2acb4d48ced7000d [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
21using ::android::sp;
22using ::android::wp;
23
24const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
25const char* kIFooDescriptor = "my-special-IFoo-class";
26
27struct IFoo_Class_Data {
28 sp<IFoo> foo;
29};
30
31void* IFoo_Class_onCreate(void* args) {
32 IFoo_Class_Data* foo = static_cast<IFoo_Class_Data*>(args);
33 // This is a foo, but we're currently not verifying that. So, the method newLocalBinder is
34 // coupled with this.
35 return static_cast<void*>(foo);
36}
37
38void IFoo_Class_onDestroy(void* userData) {
39 delete static_cast<IFoo_Class_Data*>(userData);
40}
41
42binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in,
43 AParcel* out) {
Steven Moreland5d62e442018-09-13 15:01:02 -070044 binder_status_t stat = STATUS_FAILED_TRANSACTION;
Steven Moreland2e87adc2018-08-20 19:47:00 -070045
46 sp<IFoo> foo = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder))->foo;
47 CHECK(foo != nullptr) << "Transaction made on already deleted object";
48
49 switch (code) {
50 case IFoo::DOFOO: {
51 int32_t valueIn;
52 stat = AParcel_readInt32(in, &valueIn);
Steven Moreland5d62e442018-09-13 15:01:02 -070053 if (stat != STATUS_OK) break;
Steven Moreland2e87adc2018-08-20 19:47:00 -070054 int32_t valueOut = foo->doubleNumber(valueIn);
55 stat = AParcel_writeInt32(out, valueOut);
56 break;
57 }
58 }
59
60 return stat;
61}
62
63AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate,
64 IFoo_Class_onDestroy, IFoo_Class_onTransact);
65
66class BpFoo : public IFoo {
Steven Moreland6cf66ac2018-11-02 18:14:54 -070067 public:
Steven Moreland2e87adc2018-08-20 19:47:00 -070068 BpFoo(AIBinder* binder) : mBinder(binder) {}
69 virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
70
71 virtual int32_t doubleNumber(int32_t in) {
72 AParcel* parcelIn;
Steven Moreland5d62e442018-09-13 15:01:02 -070073 CHECK(STATUS_OK == AIBinder_prepareTransaction(mBinder, &parcelIn));
Steven Moreland2e87adc2018-08-20 19:47:00 -070074
Steven Moreland5d62e442018-09-13 15:01:02 -070075 CHECK(STATUS_OK == AParcel_writeInt32(parcelIn, in));
Steven Moreland2e87adc2018-08-20 19:47:00 -070076
77 AParcel* parcelOut;
Steven Moreland5d62e442018-09-13 15:01:02 -070078 CHECK(STATUS_OK ==
Steven Moreland2e87adc2018-08-20 19:47:00 -070079 AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, &parcelOut, 0 /*flags*/));
80
81 int32_t out;
Steven Moreland5d62e442018-09-13 15:01:02 -070082 CHECK(STATUS_OK == AParcel_readInt32(parcelOut, &out));
Steven Moreland2e87adc2018-08-20 19:47:00 -070083
Steven Moreland9b80e282018-09-19 13:57:23 -070084 AParcel_delete(parcelOut);
Steven Morelandcaa776c2018-09-04 13:48:11 -070085
Steven Moreland2e87adc2018-08-20 19:47:00 -070086 return out;
87 }
88
Steven Moreland6cf66ac2018-11-02 18:14:54 -070089 private:
Steven Moreland2e87adc2018-08-20 19:47:00 -070090 // Always assumes one refcount
91 AIBinder* mBinder;
92};
93
94IFoo::~IFoo() {
Steven Moreland9b80e282018-09-19 13:57:23 -070095 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -070096}
97
98binder_status_t IFoo::addService(const char* instance) {
99 AIBinder* binder = nullptr;
100
101 if (mWeakBinder != nullptr) {
102 // one strong ref count of binder
103 binder = AIBinder_Weak_promote(mWeakBinder);
104 }
105 if (binder == nullptr) {
106 // or one strong refcount here
107 binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
108 if (mWeakBinder != nullptr) {
Steven Moreland9b80e282018-09-19 13:57:23 -0700109 AIBinder_Weak_delete(mWeakBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700110 }
111 mWeakBinder = AIBinder_Weak_new(binder);
112 }
113
114 binder_status_t status = AServiceManager_addService(binder, instance);
115 // Strong references we care about kept by remote process
116 AIBinder_decStrong(binder);
117 return status;
118}
119
120sp<IFoo> IFoo::getService(const char* instance) {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700121 AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
Steven Moreland2e87adc2018-08-20 19:47:00 -0700122 if (binder == nullptr) {
123 return nullptr;
124 }
125
Steven Moreland71cddc32018-08-30 23:39:22 -0700126 if (!AIBinder_associateClass(binder, IFoo::kClass)) {
127 AIBinder_decStrong(binder);
128 return nullptr;
129 }
130
Steven Moreland2e87adc2018-08-20 19:47:00 -0700131 if (AIBinder_isRemote(binder)) {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700132 sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder
Steven Moreland2e87adc2018-08-20 19:47:00 -0700133 return ret;
134 }
135
136 IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder));
137
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700138 CHECK(data != nullptr); // always created with non-null data
Steven Moreland2e87adc2018-08-20 19:47:00 -0700139
140 sp<IFoo> ret = data->foo;
141
142 AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder);
143 CHECK(held == binder);
144 AIBinder_decStrong(held);
145
146 // IFoo only keeps a weak reference to AIBinder, so we can drop this
147 AIBinder_decStrong(binder);
148 return ret;
149}