| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 21 | #include <android/binder_auto_utils.h> | 
|  | 22 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 23 | using ::android::sp; | 
|  | 24 | using ::android::wp; | 
|  | 25 |  | 
|  | 26 | const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo"; | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 27 | const char* IFoo::kInstanceNameToDieFor = "libbinder_ndk-test-IFoo-to-die"; | 
| Stephen Crane | 8fde87f | 2020-11-17 15:06:11 -0800 | [diff] [blame] | 28 | const char* IFoo::kIFooDescriptor = "my-special-IFoo-class"; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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) { | 
| Steven Moreland | 5d62e44 | 2018-09-13 15:01:02 -0700 | [diff] [blame] | 47 | binder_status_t stat = STATUS_FAILED_TRANSACTION; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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; | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 55 | int32_t valueOut; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 56 | stat = AParcel_readInt32(in, &valueIn); | 
| Steven Moreland | 5d62e44 | 2018-09-13 15:01:02 -0700 | [diff] [blame] | 57 | if (stat != STATUS_OK) break; | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 58 | stat = foo->doubleNumber(valueIn, &valueOut); | 
|  | 59 | if (stat != STATUS_OK) break; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 60 | stat = AParcel_writeInt32(out, valueOut); | 
|  | 61 | break; | 
|  | 62 | } | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 63 | case IFoo::DIE: { | 
|  | 64 | stat = foo->die(); | 
|  | 65 | break; | 
|  | 66 | } | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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 { | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 76 | public: | 
| Chih-Hung Hsieh | 5ca1ea4 | 2018-12-20 15:42:22 -0800 | [diff] [blame] | 77 | explicit BpFoo(AIBinder* binder) : mBinder(binder) {} | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 78 | virtual ~BpFoo() { AIBinder_decStrong(mBinder); } | 
|  | 79 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 80 | virtual binder_status_t doubleNumber(int32_t in, int32_t* out) { | 
|  | 81 | binder_status_t stat = STATUS_OK; | 
|  | 82 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 83 | AParcel* parcelIn; | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 84 | stat = AIBinder_prepareTransaction(mBinder, &parcelIn); | 
|  | 85 | if (stat != STATUS_OK) return stat; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 86 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 87 | stat = AParcel_writeInt32(parcelIn, in); | 
|  | 88 | if (stat != STATUS_OK) return stat; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 89 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 90 | ::ndk::ScopedAParcel parcelOut; | 
|  | 91 | stat = AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, parcelOut.getR(), 0 /*flags*/); | 
|  | 92 | if (stat != STATUS_OK) return stat; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 93 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 94 | stat = AParcel_readInt32(parcelOut.get(), out); | 
|  | 95 | if (stat != STATUS_OK) return stat; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 96 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 97 | return stat; | 
|  | 98 | } | 
| Steven Moreland | caa776c | 2018-09-04 13:48:11 -0700 | [diff] [blame] | 99 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 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; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 110 | } | 
|  | 111 |  | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 112 | private: | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 113 | // Always assumes one refcount | 
|  | 114 | AIBinder* mBinder; | 
|  | 115 | }; | 
|  | 116 |  | 
|  | 117 | IFoo::~IFoo() { | 
| Steven Moreland | 9b80e28 | 2018-09-19 13:57:23 -0700 | [diff] [blame] | 118 | AIBinder_Weak_delete(mWeakBinder); | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
| Steven Moreland | 8823407 | 2020-08-06 19:32:45 +0000 | [diff] [blame] | 121 | AIBinder* IFoo::getBinder() { | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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 Moreland | 9b80e28 | 2018-09-19 13:57:23 -0700 | [diff] [blame] | 132 | AIBinder_Weak_delete(mWeakBinder); | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 133 | } | 
|  | 134 | mWeakBinder = AIBinder_Weak_new(binder); | 
| Steven Moreland | 8823407 | 2020-08-06 19:32:45 +0000 | [diff] [blame] | 135 |  | 
|  | 136 | // WARNING: it is important that this class does not implement debug or | 
|  | 137 | // shell functions because it does not use special C++ wrapper | 
|  | 138 | // functions, and so this is how we test those functions. | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 139 | } | 
|  | 140 |  | 
| Steven Moreland | 8823407 | 2020-08-06 19:32:45 +0000 | [diff] [blame] | 141 | return binder; | 
|  | 142 | } | 
|  | 143 |  | 
|  | 144 | binder_status_t IFoo::addService(const char* instance) { | 
|  | 145 | AIBinder* binder = getBinder(); | 
|  | 146 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 147 | binder_status_t status = AServiceManager_addService(binder, instance); | 
|  | 148 | // Strong references we care about kept by remote process | 
|  | 149 | AIBinder_decStrong(binder); | 
|  | 150 | return status; | 
|  | 151 | } | 
|  | 152 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 153 | sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) { | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 154 | AIBinder* binder = AServiceManager_getService(instance);  // maybe nullptr | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 155 | if (binder == nullptr) { | 
|  | 156 | return nullptr; | 
|  | 157 | } | 
|  | 158 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 159 | if (!AIBinder_associateClass(binder, IFoo::kClass)) { | 
|  | 160 | AIBinder_decStrong(binder); | 
|  | 161 | return nullptr; | 
|  | 162 | } | 
|  | 163 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 164 | if (outBinder != nullptr) { | 
|  | 165 | AIBinder_incStrong(binder); | 
|  | 166 | *outBinder = binder; | 
|  | 167 | } | 
|  | 168 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 169 | if (AIBinder_isRemote(binder)) { | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 170 | sp<IFoo> ret = new BpFoo(binder);  // takes ownership of binder | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 171 | return ret; | 
|  | 172 | } | 
|  | 173 |  | 
|  | 174 | IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder)); | 
|  | 175 |  | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 176 | CHECK(data != nullptr);  // always created with non-null data | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 177 |  | 
|  | 178 | sp<IFoo> ret = data->foo; | 
|  | 179 |  | 
|  | 180 | AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder); | 
|  | 181 | CHECK(held == binder); | 
|  | 182 | AIBinder_decStrong(held); | 
|  | 183 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 184 | AIBinder_decStrong(binder); | 
|  | 185 | return ret; | 
|  | 186 | } |