OSDN Git Service

service: Implement IBluetooth.isMultiAdvertisementSupported()
authorArman Uguray <armansito@google.com>
Fri, 21 Aug 2015 21:59:57 +0000 (14:59 -0700)
committerArman Uguray <armansito@google.com>
Mon, 31 Aug 2015 21:24:16 +0000 (14:24 -0700)
Added the Binder bindings, bluetoothtbd implementation, and new
bluetooth-cli command for testing it.

Bug: 23227962
Change-Id: I2de62e49e5d8b0bcc118ccb654d72fdd9f11f748

service/adapter.cpp
service/adapter.h
service/client/main.cpp
service/hal/fake_bluetooth_interface.cpp
service/hal/fake_bluetooth_interface.h
service/ipc/binder/IBluetooth.cpp
service/ipc/binder/IBluetooth.h
service/ipc/binder/bluetooth_binder_server.cpp
service/ipc/binder/bluetooth_binder_server.h
service/test/adapter_unittest.cpp

index aba6c4c..6e3fdd7 100644 (file)
@@ -27,6 +27,15 @@ const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
 // static
 const char Adapter::kDefaultName[] = "not-initialized";
 
+// The minimum number of advertising instances required for multi-advertisement
+// support.
+//
+// TODO(armansito): This number comes straight from
+// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
+// nice to know if there were a way to obtain this number from the stack instead
+// of hardcoding it here.
+const char kMinAdvInstancesForMultiAdv = 5;
+
 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
                                               AdapterState prev_state,
                                               AdapterState new_state) {
@@ -37,6 +46,7 @@ Adapter::Adapter()
     : state_(ADAPTER_STATE_OFF),
       address_(kDefaultAddress),
       name_(kDefaultName) {
+  memset(&local_le_features_, 0, sizeof(local_le_features_));
   hal::BluetoothInterface::Get()->AddObserver(this);
   hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
 }
@@ -145,6 +155,10 @@ std::string Adapter::GetAddress() const {
   return address_.Get();
 }
 
+bool Adapter::IsMultiAdvertisementSupported() const {
+  return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
+}
+
 void Adapter::AdapterStateChangedCallback(bt_state_t state) {
   LOG(INFO) << "Adapter state changed: " << BtStateText(state);
 
@@ -193,6 +207,18 @@ void Adapter::AdapterPropertiesCallback(bt_status_t status,
         name_.Set(name);
         break;
       }
+      case BT_PROPERTY_LOCAL_LE_FEATURES: {
+        if (property->len != sizeof(bt_local_le_features_t)) {
+          LOG(WARNING) << "Malformed value received for property: "
+                       << "BT_PROPERTY_LOCAL_LE_FEATURES";
+          break;
+        }
+        bt_local_le_features_t* features =
+            reinterpret_cast<bt_local_le_features_t*>(property->val);
+        memcpy(&local_le_features_, features, sizeof(*features));
+        LOG(INFO) << "Supported LE features updated";
+        break;
+      }
       default:
         VLOG(1) << "Unhandled adapter property: "
                 << BtPropertyText(property->type);
index dc543fc..dececd6 100644 (file)
@@ -84,6 +84,10 @@ class Adapter : hal::BluetoothInterface::Observer {
   // Returns the local adapter addess in string form (XX:XX:XX:XX:XX:XX).
   std::string GetAddress() const;
 
+  // Returns true if the local adapter supports the Low-Energy
+  // multi-advertisement feature.
+  bool IsMultiAdvertisementSupported() const;
+
  private:
   // hal::BluetoothInterface::Observer overrides.
   void AdapterStateChangedCallback(bt_state_t state) override;
@@ -108,6 +112,11 @@ class Adapter : hal::BluetoothInterface::Observer {
   // The current local adapter name.
   util::AtomicString name_;
 
+  // The current set of supported LE features as obtained from the stack. The
+  // values here are all initially set to 0 and updated when the corresponding
+  // adapter property has been received from the stack.
+  bt_local_le_features_t local_le_features_;
+
   // List of observers that are interested in notifications from us.
   std::mutex observers_lock_;
   base::ObserverList<Observer> observers_;
index d3cefa1..5a3816d 100644 (file)
@@ -170,6 +170,15 @@ void HandleAdapterInfo(IBluetooth* bt_iface, const vector<string>& args) {
   PrintFieldAndValue("\tState", bluetooth::AdapterStateToString(
       static_cast<bluetooth::AdapterState>(bt_iface->GetState())));
   PrintFieldAndValue("\tName", bt_iface->GetName());
+  PrintFieldAndBoolValue("\tMulti-Adv. supported",
+                         bt_iface->IsMultiAdvertisementSupported());
+}
+
+void HandleSupportsMultiAdv(IBluetooth* bt_iface, const vector<string>& args) {
+  CHECK_NO_ARGS(args);
+
+  bool status = bt_iface->IsMultiAdvertisementSupported();
+  PrintFieldAndBoolValue("Multi-advertisement support", status);
 }
 
 void HandleHelp(IBluetooth* bt_iface, const vector<string>& args);
@@ -189,6 +198,8 @@ struct {
   { "set-local-name", HandleSetLocalName, "\t\tSet the local adapter name" },
   { "get-local-name", HandleGetLocalName, "\t\tGet the local adapter name" },
   { "adapter-info", HandleAdapterInfo, "\t\tPrint adapter properties" },
+  { "supports-multi-adv", HandleSupportsMultiAdv,
+    "\tWhether multi-advertisement is currently supported" },
   {},
 };
 
index fb4980a..6a2309c 100644 (file)
@@ -124,6 +124,16 @@ void FakeBluetoothInterface::NotifyAdapterAddressPropertyChanged(
   NotifyAdapterPropertiesChanged(1, &property);
 }
 
+void FakeBluetoothInterface::NotifyAdapterLocalLeFeaturesPropertyChanged(
+      const bt_local_le_features_t* features) {
+  bt_property_t property;
+  property.len = sizeof(*features);
+  property.val = (void*)features;
+  property.type = BT_PROPERTY_LOCAL_LE_FEATURES;
+
+  NotifyAdapterPropertiesChanged(1, &property);
+}
+
 void FakeBluetoothInterface::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
index 49f424d..4297eb3 100644 (file)
@@ -50,6 +50,8 @@ class FakeBluetoothInterface : public BluetoothInterface {
                                       bt_property_t* properties);
   void NotifyAdapterNamePropertyChanged(const std::string& name);
   void NotifyAdapterAddressPropertyChanged(const bt_bdaddr_t* address);
+  void NotifyAdapterLocalLeFeaturesPropertyChanged(
+      const bt_local_le_features_t* features);
 
   // hal::BluetoothInterface overrides:
   void AddObserver(Observer* observer) override;
index dd9781c..e14dbcf 100644 (file)
@@ -35,7 +35,7 @@ namespace binder {
 const char IBluetooth::kBluetoothServiceName[] = "bluetooth-service";
 
 // static
-android::sp<IBluetooth> IBluetooth::getClientInterface() {
+sp<IBluetooth> IBluetooth::getClientInterface() {
   sp<IServiceManager> sm = defaultServiceManager();
   if (!sm.get()) {
     LOG(ERROR) << "Failed to obtain a handle to the default Service Manager";
@@ -121,6 +121,11 @@ android::status_t BnBluetooth::onTransact(
       UnregisterCallback(interface_cast<IBluetoothCallback>(callback));
       return android::NO_ERROR;
     }
+    case IS_MULTI_ADVERTISEMENT_SUPPORTED_TRANSACTION: {
+      bool result = IsMultiAdvertisementSupported();
+      reply->writeInt32(result);
+      return android::NO_ERROR;
+    }
     default:
       return BBinder::onTransact(code, data, reply, flags);
   }
@@ -231,6 +236,17 @@ void BpBluetooth::UnregisterCallback(const sp<IBluetoothCallback>& callback) {
   remote()->transact(IBluetooth::UNREGISTER_CALLBACK_TRANSACTION, data, &reply);
 }
 
+bool BpBluetooth::IsMultiAdvertisementSupported() {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+
+  remote()->transact(IBluetooth::IS_MULTI_ADVERTISEMENT_SUPPORTED_TRANSACTION,
+                     data, &reply);
+
+  return reply.readInt32();
+}
+
 IMPLEMENT_META_INTERFACE(Bluetooth, IBluetooth::kBluetoothServiceName);
 
 }  // namespace binder
index a40af70..6a2e32b 100644 (file)
@@ -142,7 +142,10 @@ class IBluetooth : public android::IInterface {
   virtual void UnregisterCallback(
       const android::sp<IBluetoothCallback>& callback) = 0;
 
+  virtual bool IsMultiAdvertisementSupported() = 0;
+
   // TODO(armansito): Complete the API definition.
+
  private:
   DISALLOW_COPY_AND_ASSIGN(IBluetooth);
 };
@@ -162,6 +165,8 @@ class BnBluetooth : public android::BnInterface<IBluetooth> {
       const android::Parcel& data,
       android::Parcel* reply,
       uint32_t flags = 0);
+
+  DISALLOW_COPY_AND_ASSIGN(BnBluetooth);
 };
 
 // The Binder client interface to IBluetooth.
@@ -176,15 +181,19 @@ class BpBluetooth : public android::BpInterface<IBluetooth> {
   bool Enable() override;
   bool EnableNoAutoConnect() override;
   bool Disable() override;
+
   std::string GetAddress() override;
   std::vector<bluetooth::UUID> GetUUIDs() override;
   bool SetName(const std::string& name) override;
   std::string GetName() override;
+
   void RegisterCallback(
       const android::sp<IBluetoothCallback>& callback) override;
   void UnregisterCallback(
       const android::sp<IBluetoothCallback>& callback) override;
 
+  bool IsMultiAdvertisementSupported() override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(BpBluetooth);
 };
index 3a1631b..43568ee 100644 (file)
@@ -97,6 +97,11 @@ void BluetoothBinderServer::UnregisterCallback(
   callbacks_.Unregister(callback);
 }
 
+bool BluetoothBinderServer::IsMultiAdvertisementSupported() {
+  VLOG(2) << __func__;
+  return adapter_->IsMultiAdvertisementSupported();
+}
+
 void BluetoothBinderServer::OnAdapterStateChanged(
     bluetooth::Adapter* adapter,
     bluetooth::AdapterState prev_state,
index cf0069e..e6e708b 100644 (file)
@@ -54,6 +54,8 @@ class BluetoothBinderServer : public BnBluetooth,
   void UnregisterCallback(
       const android::sp<IBluetoothCallback>& callback) override;
 
+  bool IsMultiAdvertisementSupported() override;
+
   // bluetooth::Adapter::Observer overrides:
   void OnAdapterStateChanged(bluetooth::Adapter* adapter,
                              bluetooth::AdapterState prev_state,
index 09d2cfa..6d67d7e 100644 (file)
@@ -211,5 +211,20 @@ TEST_F(AdapterTest, GetAddress) {
   EXPECT_EQ(kTestAdapterAddressOutput, adapter_->GetAddress());
 }
 
+TEST_F(AdapterTest, IsMultiAdvertisementSupported) {
+  EXPECT_FALSE(adapter_->IsMultiAdvertisementSupported());
+
+  bt_local_le_features_t features;
+  memset(&features, 0, sizeof(features));
+
+  features.max_adv_instance = 10;  // Some high number.
+  fake_hal_iface_->NotifyAdapterLocalLeFeaturesPropertyChanged(&features);
+  EXPECT_TRUE(adapter_->IsMultiAdvertisementSupported());
+
+  features.max_adv_instance = 0;  // Low number.
+  fake_hal_iface_->NotifyAdapterLocalLeFeaturesPropertyChanged(&features);
+  EXPECT_FALSE(adapter_->IsMultiAdvertisementSupported());
+}
+
 }  // namespace
 }  // namespace bluetooth