• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_manager.h>
19 #include <iface/iface.h>
20 
21 #include <android/binder_auto_utils.h>
22 
23 using ::android::sp;
24 using ::android::wp;
25 
26 const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
27 const char* IFoo::kInstanceNameToDieFor = "libbinder_ndk-test-IFoo-to-die";
28 const char* IFoo::kInstanceNameToDieFor2 = "libbinder_ndk-test-IFoo-to-die2";
29 const char* IFoo::kIFooDescriptor = "my-special-IFoo-class";
30 
31 struct IFoo_Class_Data {
32     sp<IFoo> foo;
33 };
34 
IFoo_Class_onCreate(void * args)35 void* 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 
IFoo_Class_onDestroy(void * userData)42 void IFoo_Class_onDestroy(void* userData) {
43     delete static_cast<IFoo_Class_Data*>(userData);
44 }
45 
IFoo_Class_onTransact(AIBinder * binder,transaction_code_t code,const AParcel * in,AParcel * out)46 binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in,
47                                       AParcel* out) {
48     binder_status_t stat = STATUS_FAILED_TRANSACTION;
49 
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;
56             int32_t valueOut;
57             stat = AParcel_readInt32(in, &valueIn);
58             if (stat != STATUS_OK) break;
59             stat = foo->doubleNumber(valueIn, &valueOut);
60             if (stat != STATUS_OK) break;
61             stat = AParcel_writeInt32(out, valueOut);
62             break;
63         }
64         case IFoo::DIE: {
65             stat = foo->die();
66             break;
67         }
68     }
69 
70     return stat;
71 }
72 
73 AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate,
74                                                      IFoo_Class_onDestroy, IFoo_Class_onTransact);
75 
76 // 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.
78 AIBinder_Class* IFoo::kClassDupe = AIBinder_Class_define(
79         kIFooDescriptor, IFoo_Class_onCreate, IFoo_Class_onDestroy, IFoo_Class_onTransact);
80 
81 class BpFoo : public IFoo {
82    public:
BpFoo(AIBinder * binder)83     explicit BpFoo(AIBinder* binder) : mBinder(binder) {}
~BpFoo()84     virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
85 
doubleNumber(int32_t in,int32_t * out)86     virtual binder_status_t doubleNumber(int32_t in, int32_t* out) {
87         binder_status_t stat = STATUS_OK;
88 
89         AParcel* parcelIn;
90         stat = AIBinder_prepareTransaction(mBinder, &parcelIn);
91         if (stat != STATUS_OK) return stat;
92 
93         stat = AParcel_writeInt32(parcelIn, in);
94         if (stat != STATUS_OK) return stat;
95 
96         ::ndk::ScopedAParcel parcelOut;
97         stat = AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, parcelOut.getR(), 0 /*flags*/);
98         if (stat != STATUS_OK) return stat;
99 
100         stat = AParcel_readInt32(parcelOut.get(), out);
101         if (stat != STATUS_OK) return stat;
102 
103         return stat;
104     }
105 
die()106     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;
116     }
117 
118    private:
119     // Always assumes one refcount
120     AIBinder* mBinder;
121 };
122 
~IFoo()123 IFoo::~IFoo() {
124     AIBinder_Weak_delete(mWeakBinder);
125 }
126 
getBinder()127 AIBinder* IFoo::getBinder() {
128     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) {
138             AIBinder_Weak_delete(mWeakBinder);
139         }
140         mWeakBinder = AIBinder_Weak_new(binder);
141 
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.
145     }
146 
147     return binder;
148 }
149 
addService(const char * instance)150 binder_status_t IFoo::addService(const char* instance) {
151     AIBinder* binder = getBinder();
152 
153     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 
getService(const char * instance,AIBinder ** outBinder)159 sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) {
160 #pragma clang diagnostic push
161 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
162     AIBinder* binder = AServiceManager_getService(instance);  // maybe nullptr
163 #pragma clang diagnostic pop
164     if (binder == nullptr) {
165         return nullptr;
166     }
167 
168     if (!AIBinder_associateClass(binder, IFoo::kClass)) {
169         AIBinder_decStrong(binder);
170         return nullptr;
171     }
172 
173     if (outBinder != nullptr) {
174         AIBinder_incStrong(binder);
175         *outBinder = binder;
176     }
177 
178     if (AIBinder_isRemote(binder)) {
179         sp<IFoo> ret = new BpFoo(binder);  // takes ownership of binder
180         return ret;
181     }
182 
183     IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder));
184 
185     CHECK(data != nullptr);  // always created with non-null data
186 
187     sp<IFoo> ret = data->foo;
188 
189     AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder);
190     CHECK(held == binder);
191     AIBinder_decStrong(held);
192 
193     AIBinder_decStrong(binder);
194     return ret;
195 }
196