1 // 2 // Copyright (C) 2015 Google, Inc. 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 "service/ipc/binder/interface_with_instances_base.h" 18 19 #include <base/logging.h> 20 21 namespace ipc { 22 namespace binder { 23 24 bool InterfaceWithInstancesBase::RegisterInstanceBase( 25 const android::sp<IInterface>& callback, 26 bluetooth::BluetoothInstanceFactory* factory) { 27 VLOG(2) << __func__; 28 CHECK(factory); 29 30 if (!callback.get()) { 31 LOG(ERROR) << "Cannot register a NULL callback"; 32 return false; 33 } 34 35 // Store the callback in the pending list. It will get removed later when the 36 // stack notifies us asynchronously. 37 bluetooth::UUID app_uuid = bluetooth::UUID::GetRandom(); 38 if (!pending_callbacks_.Register(app_uuid, callback)) { 39 LOG(ERROR) << "Failed to store |callback| to map"; 40 return false; 41 } 42 43 // Create a weak pointer and pass that to the callback to prevent an invalid 44 // access later. Since this object is managed using Android's StrongPointer 45 // (sp) we are using a wp here rather than std::weak_ptr. 46 android::wp<InterfaceWithInstancesBase> weak_ptr_to_this(this); 47 48 bluetooth::BluetoothInstanceFactory::RegisterCallback cb = 49 [weak_ptr_to_this]( 50 bluetooth::BLEStatus status, 51 const bluetooth::UUID& in_uuid, 52 std::unique_ptr<bluetooth::BluetoothInstance> instance) { 53 // If the weak pointer was invalidated then there is nothing we can do. 54 android::sp<InterfaceWithInstancesBase> strong_ptr_to_this = 55 weak_ptr_to_this.promote(); 56 if (!strong_ptr_to_this.get()) { 57 VLOG(2) << "InterfaceWithInstancesBase was deleted while instance was" 58 << " being registered"; 59 return; 60 } 61 62 strong_ptr_to_this->OnRegisterInstance( 63 status, in_uuid, std::move(instance)); 64 }; 65 66 if (factory->RegisterInstance(app_uuid, cb)) 67 return true; 68 69 LOG(ERROR) << "Failed to register instance"; 70 pending_callbacks_.Remove(app_uuid); 71 72 return false; 73 } 74 75 void InterfaceWithInstancesBase::UnregisterInstanceBase(int instance_id) { 76 VLOG(2) << __func__; 77 std::lock_guard<std::mutex> lock(maps_lock_); 78 79 id_to_cb_.Remove(instance_id); 80 id_to_instance_.erase(instance_id); 81 } 82 83 void InterfaceWithInstancesBase::UnregisterAllBase() { 84 VLOG(2) << __func__; 85 std::lock_guard<std::mutex> lock(maps_lock_); 86 87 id_to_cb_.Clear(); 88 id_to_instance_.clear(); 89 } 90 91 android::sp<IInterface> InterfaceWithInstancesBase::GetCallback( 92 int instance_id) { 93 return id_to_cb_.Get(instance_id); 94 } 95 96 std::shared_ptr<bluetooth::BluetoothInstance> 97 InterfaceWithInstancesBase::GetInstance(int instance_id) { 98 auto iter = id_to_instance_.find(instance_id); 99 if (iter == id_to_instance_.end()) 100 return std::shared_ptr<bluetooth::BluetoothInstance>(); 101 return iter->second; 102 } 103 104 void InterfaceWithInstancesBase::OnRegisterInstance( 105 bluetooth::BLEStatus status, 106 const bluetooth::UUID& uuid, 107 std::unique_ptr<bluetooth::BluetoothInstance> instance) { 108 VLOG(2) << __func__ << " - status: " << status; 109 110 // Simply remove the callback from |pending_callbacks_| as it no longer 111 // belongs in there. 112 sp<IInterface> callback = pending_callbacks_.Remove(uuid); 113 114 // |callback| might be NULL if it was removed from the pending list, e.g. the 115 // remote process that owns the callback died. 116 if (!callback.get()) { 117 VLOG(1) << "Callback was removed before the call to \"RegisterInstance\" " 118 << "returned; unregistering instance"; 119 return; 120 } 121 122 if (status != bluetooth::BLE_STATUS_SUCCESS) { 123 // The call wasn't successful. Notify the implementation and return. 124 LOG(ERROR) << "Failed to register instance: " << status; 125 OnRegisterInstanceImpl(status, callback, nullptr); 126 return; 127 } 128 129 std::lock_guard<std::mutex> lock(maps_lock_); 130 int instance_id = instance->GetInstanceId(); 131 CHECK(instance_id); 132 if (!id_to_cb_.Register(instance_id, callback, this)) { 133 LOG(ERROR) << "Failed to store callback"; 134 OnRegisterInstanceImpl(bluetooth::BLE_STATUS_FAILURE, callback, nullptr); 135 return; 136 } 137 138 VLOG(1) << "Registered BluetoothInstance - ID: " << instance_id; 139 140 auto shared_instance = 141 std::shared_ptr<bluetooth::BluetoothInstance>(instance.release()); 142 id_to_instance_[instance_id] = shared_instance; 143 144 OnRegisterInstanceImpl(status, callback, shared_instance.get()); 145 } 146 147 void InterfaceWithInstancesBase::OnRemoteCallbackRemoved(const int& key) { 148 VLOG(2) << __func__ << " instance_id: " << key; 149 std::lock_guard<std::mutex> lock(maps_lock_); 150 151 // No need to remove from the callback map as the entry should be already 152 // removed when this callback gets called. 153 id_to_instance_.erase(key); 154 } 155 156 } // namespace binder 157 } // namespace ipc 158