| 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 |  | 
 | 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) { | 
| 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); | 
 | 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 Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 143 | sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) { | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 144 |     AIBinder* binder = AServiceManager_getService(instance);  // maybe nullptr | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 145 |     if (binder == nullptr) { | 
 | 146 |         return nullptr; | 
 | 147 |     } | 
 | 148 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 149 |     if (!AIBinder_associateClass(binder, IFoo::kClass)) { | 
 | 150 |         AIBinder_decStrong(binder); | 
 | 151 |         return nullptr; | 
 | 152 |     } | 
 | 153 |  | 
| Steven Moreland | 507547f | 2018-11-06 15:58:05 -0800 | [diff] [blame] | 154 |     if (outBinder != nullptr) { | 
 | 155 |         AIBinder_incStrong(binder); | 
 | 156 |         *outBinder = binder; | 
 | 157 |     } | 
 | 158 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 159 |     if (AIBinder_isRemote(binder)) { | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 160 |         sp<IFoo> ret = new BpFoo(binder);  // takes ownership of binder | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 161 |         return ret; | 
 | 162 |     } | 
 | 163 |  | 
 | 164 |     IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder)); | 
 | 165 |  | 
| Steven Moreland | 6cf66ac | 2018-11-02 18:14:54 -0700 | [diff] [blame] | 166 |     CHECK(data != nullptr);  // always created with non-null data | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 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 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 174 |     AIBinder_decStrong(binder); | 
 | 175 |     return ret; | 
 | 176 | } |