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* kIFooDescriptor = "my-special-IFoo-class"; 29 30 struct IFoo_Class_Data { 31 sp<IFoo> foo; 32 }; 33 34 void* 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 41 void IFoo_Class_onDestroy(void* userData) { 42 delete static_cast<IFoo_Class_Data*>(userData); 43 } 44 45 binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in, 46 AParcel* out) { 47 binder_status_t stat = STATUS_FAILED_TRANSACTION; 48 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; 55 int32_t valueOut; 56 stat = AParcel_readInt32(in, &valueIn); 57 if (stat != STATUS_OK) break; 58 stat = foo->doubleNumber(valueIn, &valueOut); 59 if (stat != STATUS_OK) break; 60 stat = AParcel_writeInt32(out, valueOut); 61 break; 62 } 63 case IFoo::DIE: { 64 stat = foo->die(); 65 break; 66 } 67 } 68 69 return stat; 70 } 71 72 AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate, 73 IFoo_Class_onDestroy, IFoo_Class_onTransact); 74 75 class BpFoo : public IFoo { 76 public: 77 explicit BpFoo(AIBinder* binder) : mBinder(binder) {} 78 virtual ~BpFoo() { AIBinder_decStrong(mBinder); } 79 80 virtual binder_status_t doubleNumber(int32_t in, int32_t* out) { 81 binder_status_t stat = STATUS_OK; 82 83 AParcel* parcelIn; 84 stat = AIBinder_prepareTransaction(mBinder, &parcelIn); 85 if (stat != STATUS_OK) return stat; 86 87 stat = AParcel_writeInt32(parcelIn, in); 88 if (stat != STATUS_OK) return stat; 89 90 ::ndk::ScopedAParcel parcelOut; 91 stat = AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, parcelOut.getR(), 0 /*flags*/); 92 if (stat != STATUS_OK) return stat; 93 94 stat = AParcel_readInt32(parcelOut.get(), out); 95 if (stat != STATUS_OK) return stat; 96 97 return stat; 98 } 99 100 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; 110 } 111 112 private: 113 // Always assumes one refcount 114 AIBinder* mBinder; 115 }; 116 117 IFoo::~IFoo() { 118 AIBinder_Weak_delete(mWeakBinder); 119 } 120 121 binder_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) { 132 AIBinder_Weak_delete(mWeakBinder); 133 } 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 143 sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) { 144 AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr 145 if (binder == nullptr) { 146 return nullptr; 147 } 148 149 if (!AIBinder_associateClass(binder, IFoo::kClass)) { 150 AIBinder_decStrong(binder); 151 return nullptr; 152 } 153 154 if (outBinder != nullptr) { 155 AIBinder_incStrong(binder); 156 *outBinder = binder; 157 } 158 159 if (AIBinder_isRemote(binder)) { 160 sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder 161 return ret; 162 } 163 164 IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder)); 165 166 CHECK(data != nullptr); // always created with non-null data 167 168 sp<IFoo> ret = data->foo; 169 170 AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder); 171 CHECK(held == binder); 172 AIBinder_decStrong(held); 173 174 AIBinder_decStrong(binder); 175 return ret; 176 } 177