Home | History | Annotate | Download | only in binder
      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 = [weak_ptr_to_this](
     49       bluetooth::BLEStatus status, const bluetooth::UUID& in_uuid,
     50       std::unique_ptr<bluetooth::BluetoothInstance> instance) {
     51     // If the weak pointer was invalidated then there is nothing we can do.
     52     android::sp<InterfaceWithInstancesBase> strong_ptr_to_this =
     53         weak_ptr_to_this.promote();
     54     if (!strong_ptr_to_this.get()) {
     55       VLOG(2) << "InterfaceWithInstancesBase was deleted while instance was"
     56               << " being registered";
     57       return;
     58     }
     59 
     60     strong_ptr_to_this->OnRegisterInstance(status, in_uuid,
     61                                            std::move(instance));
     62   };
     63 
     64   if (factory->RegisterInstance(app_uuid, cb)) return true;
     65 
     66   LOG(ERROR) << "Failed to register instance";
     67   pending_callbacks_.Remove(app_uuid);
     68 
     69   return false;
     70 }
     71 
     72 void InterfaceWithInstancesBase::UnregisterInstanceBase(int instance_id) {
     73   VLOG(2) << __func__;
     74   std::lock_guard<std::mutex> lock(maps_lock_);
     75 
     76   id_to_cb_.Remove(instance_id);
     77   id_to_instance_.erase(instance_id);
     78 }
     79 
     80 void InterfaceWithInstancesBase::UnregisterAllBase() {
     81   VLOG(2) << __func__;
     82   std::lock_guard<std::mutex> lock(maps_lock_);
     83 
     84   id_to_cb_.Clear();
     85   id_to_instance_.clear();
     86 }
     87 
     88 android::sp<IInterface> InterfaceWithInstancesBase::GetCallback(
     89     int instance_id) {
     90   return id_to_cb_.Get(instance_id);
     91 }
     92 
     93 std::shared_ptr<bluetooth::BluetoothInstance>
     94 InterfaceWithInstancesBase::GetInstance(int instance_id) {
     95   auto iter = id_to_instance_.find(instance_id);
     96   if (iter == id_to_instance_.end())
     97     return std::shared_ptr<bluetooth::BluetoothInstance>();
     98   return iter->second;
     99 }
    100 
    101 void InterfaceWithInstancesBase::OnRegisterInstance(
    102     bluetooth::BLEStatus status, const bluetooth::UUID& uuid,
    103     std::unique_ptr<bluetooth::BluetoothInstance> instance) {
    104   VLOG(2) << __func__ << " - status: " << status;
    105 
    106   // Simply remove the callback from |pending_callbacks_| as it no longer
    107   // belongs in there.
    108   sp<IInterface> callback = pending_callbacks_.Remove(uuid);
    109 
    110   // |callback| might be NULL if it was removed from the pending list, e.g. the
    111   // remote process that owns the callback died.
    112   if (!callback.get()) {
    113     VLOG(1) << "Callback was removed before the call to \"RegisterInstance\" "
    114             << "returned; unregistering instance";
    115     return;
    116   }
    117 
    118   if (status != bluetooth::BLE_STATUS_SUCCESS) {
    119     // The call wasn't successful. Notify the implementation and return.
    120     LOG(ERROR) << "Failed to register instance: " << status;
    121     OnRegisterInstanceImpl(status, callback, nullptr);
    122     return;
    123   }
    124 
    125   std::lock_guard<std::mutex> lock(maps_lock_);
    126   int instance_id = instance->GetInstanceId();
    127   if (!id_to_cb_.Register(instance_id, callback, this)) {
    128     LOG(ERROR) << "Failed to store callback";
    129     OnRegisterInstanceImpl(bluetooth::BLE_STATUS_FAILURE, callback, nullptr);
    130     return;
    131   }
    132 
    133   VLOG(1) << "Registered BluetoothInstance - ID: " << instance_id;
    134 
    135   auto shared_instance =
    136       std::shared_ptr<bluetooth::BluetoothInstance>(instance.release());
    137   id_to_instance_[instance_id] = shared_instance;
    138 
    139   OnRegisterInstanceImpl(status, callback, shared_instance.get());
    140 }
    141 
    142 void InterfaceWithInstancesBase::OnRemoteCallbackRemoved(const int& key) {
    143   VLOG(2) << __func__ << " instance_id: " << key;
    144   std::lock_guard<std::mutex> lock(maps_lock_);
    145 
    146   // No need to remove from the callback map as the entry should be already
    147   // removed when this callback gets called.
    148   id_to_instance_.erase(key);
    149 }
    150 
    151 }  // namespace binder
    152 }  // namespace ipc
    153