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