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 =
     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