OSDN Git Service

Add guest mode functionality (2/5)
authorAjay Panicker <apanicke@google.com>
Fri, 18 Mar 2016 00:09:24 +0000 (17:09 -0700)
committerAjay Panicker <apanicke@google.com>
Tue, 19 Apr 2016 06:00:20 +0000 (23:00 -0700)
Add a flag to enable() to start Bluetooth in restricted
mode. In restricted mode, all devices that are paired during
restricted mode are deleted upon leaving restricted mode.
Right now restricted mode is only entered while a guest
user is active.

Bug: 27410683
Change-Id: I8f23d28ef0aa3a8df13d469c73005c8e1b894d19

17 files changed:
btif/include/btif_api.h
btif/include/btif_storage.h
btif/src/bluetooth.c
btif/src/btif_config.c
btif/src/btif_storage.c
service/adapter.cpp
service/adapter.h
service/client/main.cpp
service/common/bluetooth/binder/IBluetooth.cpp
service/common/bluetooth/binder/IBluetooth.h
service/hal/fake_bluetooth_interface.cpp
service/ipc/binder/bluetooth_binder_server.cpp
service/ipc/binder/bluetooth_binder_server.h
service/test/adapter_unittest.cpp
service/test/mock_adapter.h
test/suite/adapter/adapter_unittest.cpp
test/suite/gatt/gatt_test.cpp

index dcaecfc..ed67b9e 100644 (file)
@@ -89,6 +89,23 @@ bt_status_t btif_shutdown_bluetooth(void);
 
 /*******************************************************************************
 **
+** Function         is_restricted_mode
+**
+** Description      Checks if BT was enabled in restriced mode. In restricted
+**                  mode, bonds that are created are marked as temporary.
+**                  These bonds persist until we leave restricted mode, at
+**                  which point they will be deleted from the config. Also
+**                  while in restricted mode, the user can access devices
+**                  that are already paired before entering restricted mode,
+**                  but they cannot remove any of these devices.
+**
+** Returns          bool
+**
+*******************************************************************************/
+bool is_restricted_mode(void);
+
+/*******************************************************************************
+**
 ** Function         btif_get_adapter_properties
 **
 ** Description      Fetches all local adapter properties
index 03debef..bc1060c 100644 (file)
@@ -262,6 +262,18 @@ bt_status_t btif_storage_load_bonded_hid_info(void);
 *******************************************************************************/
 bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr);
 
+/*******************************************************************************
+**
+** Function         btif_storage_is_retricted_device
+**
+** Description      BTIF storage API - checks if this device is a restricted device
+**
+** Returns          TRUE  if the device is labled as restricted
+**                  FALSE otherwise
+**
+*******************************************************************************/
+BOOLEAN btif_storage_is_restricted_device(const bt_bdaddr_t *remote_bd_addr);
+
 #if (BLE_INCLUDED == TRUE)
 bt_status_t btif_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
                                               char *key,
index e0399ab..1414138 100644 (file)
@@ -59,6 +59,7 @@
 #include "osi/include/wakelock.h"
 #include "stack_manager.h"
 #include "btif_config.h"
+#include "btif_storage.h"
 #include "btif/include/btif_debug_btsnoop.h"
 #include "btif/include/btif_debug_conn.h"
 #include "btif/include/btif_media.h"
@@ -68,6 +69,7 @@
 ************************************************************************************/
 
 bt_callbacks_t *bt_hal_cbacks = NULL;
+bool restricted_mode = FALSE;
 
 /************************************************************************************
 **  Externs
@@ -139,8 +141,10 @@ static int init(bt_callbacks_t *callbacks) {
   return BT_STATUS_SUCCESS;
 }
 
-static int enable(void) {
-  LOG_INFO(LOG_TAG, "%s", __func__);
+static int enable(bool start_restricted) {
+  LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted);
+
+  restricted_mode = start_restricted;
 
   if (!interface_ready())
     return BT_STATUS_NOT_READY;
@@ -161,6 +165,10 @@ static void cleanup(void) {
   stack_manager_get_interface()->clean_up_stack();
 }
 
+bool is_restricted_mode() {
+  return restricted_mode;
+}
+
 static int get_adapter_properties(void)
 {
     /* sanity check */
@@ -281,6 +289,9 @@ static int cancel_bond(const bt_bdaddr_t *bd_addr)
 
 static int remove_bond(const bt_bdaddr_t *bd_addr)
 {
+    if (is_restricted_mode() && !btif_storage_is_restricted_device(bd_addr))
+        return BT_STATUS_SUCCESS;
+
     /* sanity check */
     if (interface_ready() == FALSE)
         return BT_STATUS_NOT_READY;
index 64b5818..fd5ee69 100644 (file)
@@ -30,6 +30,7 @@
 #include "bt_types.h"
 #include "btcore/include/bdaddr.h"
 #include "btcore/include/module.h"
+#include "btif_api.h"
 #include "btif_common.h"
 #include "btif_config.h"
 #include "btif_config_transcode.h"
@@ -67,6 +68,7 @@ static void btif_config_write(UINT16 event, char *p_param);
 static bool is_factory_reset(void);
 static void delete_config_files(void);
 static void btif_config_remove_unpaired(config_t *config);
+static void btif_config_remove_restricted(config_t *config);
 
 static enum ConfigSource {
   NOT_LOADED,
@@ -153,6 +155,10 @@ static future_t *init(void) {
 
   btif_config_remove_unpaired(config);
 
+  // Cleanup temporary pairings if we have left guest mode
+  if (!is_restricted_mode())
+    btif_config_remove_restricted(config);
+
   // TODO(sharvil): use a non-wake alarm for this once we have
   // API support for it. There's no need to wake the system to
   // write back to disk.
@@ -499,6 +505,22 @@ void btif_debug_config_dump(int fd) {
     pthread_mutex_unlock(&lock);
 }
 
+static void btif_config_remove_restricted(config_t* config) {
+  assert(config != NULL);
+
+  pthread_mutex_lock(&lock);
+  const config_section_node_t *snode = config_section_begin(config);
+  while (snode != config_section_end(config)) {
+    const char *section = config_section_name(snode);
+    if (string_is_bdaddr(section) && config_has_key(config, section, "Restricted")) {
+        BTIF_TRACE_DEBUG("%s: Removing restricted device %s", __func__, section);
+        config_remove_section(config, section);
+    }
+    snode = config_section_next(snode);
+  }
+  pthread_mutex_unlock(&lock);
+}
+
 static bool is_factory_reset(void) {
   char factory_reset[PROPERTY_VALUE_MAX] = {0};
   property_get("persist.bluetooth.factoryreset", factory_reset, "false");
index e058a14..791203f 100644 (file)
@@ -793,6 +793,13 @@ bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
     int ret = btif_config_set_int(bdstr, "LinkKeyType", (int)key_type);
     ret &= btif_config_set_int(bdstr, "PinLength", (int)pin_length);
     ret &= btif_config_set_bin(bdstr, "LinkKey", link_key, sizeof(LINK_KEY));
+
+    if (is_restricted_mode()) {
+        BTIF_TRACE_WARNING("%s: '%s' pairing will be removed if unrestricted",
+                         __func__, bdstr);
+        btif_config_set_int(bdstr, "Restricted", 1);
+    }
+
     /* write bonded info immediately */
     btif_config_flush();
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
@@ -1474,3 +1481,20 @@ bt_status_t btif_storage_read_hl_apps_cb(char *value, int value_size)
     return bt_status;
 }
 
+/*******************************************************************************
+**
+** Function         btif_storage_is_restricted_device
+**
+** Description      BTIF storage API - checks if this device is a restricted device
+**
+** Returns          TRUE  if the device is labeled as restricted
+**                  FALSE otherwise
+**
+*******************************************************************************/
+BOOLEAN btif_storage_is_restricted_device(const bt_bdaddr_t *remote_bd_addr)
+{
+    bdstr_t bdstr;
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+
+    return btif_config_exist(bdstr, "Restricted");
+}
index 891bc08..45826b2 100644 (file)
@@ -105,7 +105,7 @@ class AdapterImpl : public Adapter,
     return state_.load() == ADAPTER_STATE_ON;
   }
 
-  bool Enable() override {
+  bool Enable(bool start_restricted) override {
     AdapterState current_state = GetState();
     if (current_state != ADAPTER_STATE_OFF) {
       LOG(INFO) << "Adapter not disabled - state: "
@@ -118,7 +118,7 @@ class AdapterImpl : public Adapter,
     state_ = ADAPTER_STATE_TURNING_ON;
     NotifyAdapterStateChanged(current_state, state_);
 
-    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
+    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(start_restricted);
     if (status != BT_STATUS_SUCCESS) {
       LOG(ERROR) << "Failed to enable Bluetooth - status: "
                  << BtStatusText((const bt_status_t)status);
index 8594f20..11226ce 100644 (file)
@@ -82,7 +82,10 @@ class Adapter {
   // to the controller, otherwise returns false. A successful call to this
   // method only means that the enable request has been sent to the Bluetooth
   // controller and does not imply that the operation itself succeeded.
-  virtual bool Enable() = 0;
+  // The |start_restricted| flag enables the adapter in restricted mode. In
+  // restricted mode, bonds that are created are marked as restricted in the
+  // config file. These devices are deleted upon leaving restricted mode.
+  virtual bool Enable(bool start_restricted) = 0;
 
   // Powers off the Bluetooth radio. Returns true, if the disable request was
   // successfully sent to the Bluetooth controller.
index 078e1ff..87fdaf5 100644 (file)
@@ -259,8 +259,24 @@ void HandleDisable(IBluetooth* bt_iface, const vector<string>& args) {
 }
 
 void HandleEnable(IBluetooth* bt_iface, const vector<string>& args) {
-  CHECK_NO_ARGS(args);
-  PrintCommandStatus(bt_iface->Enable());
+  bool is_restricted_mode = false;
+
+  for (auto iter : args) {
+    const std::string& arg = iter;
+    if (arg == "-h") {
+      static const char kUsage[] =
+          "Usage: start-adv [flags]\n"
+          "\n"
+          "Flags:\n"
+          "\t--restricted|-r\tStart in restricted mode\n";
+      cout << kUsage << endl;
+      return;
+    } else if (arg == "--restricted" || arg == "-r") {
+      is_restricted_mode = true;
+    }
+  }
+
+  PrintCommandStatus(bt_iface->Enable(is_restricted_mode));
 }
 
 void HandleGetState(IBluetooth* bt_iface, const vector<string>& args) {
@@ -697,7 +713,7 @@ struct {
 } kCommandMap[] = {
   { "help", HandleHelp, "\t\t\tDisplay this message" },
   { "disable", HandleDisable, "\t\t\tDisable Bluetooth" },
-  { "enable", HandleEnable, "\t\t\tEnable Bluetooth" },
+  { "enable", HandleEnable, "\t\t\tEnable Bluetooth (-h for options)" },
   { "get-state", HandleGetState, "\t\tGet the current adapter state" },
   { "is-enabled", HandleIsEnabled, "\t\tReturn if Bluetooth is enabled" },
   { "get-local-address", HandleGetLocalAddress,
index 65d1307..3fb0916 100644 (file)
@@ -81,7 +81,8 @@ status_t BnBluetooth::onTransact(
     }
     case ENABLE_TRANSACTION: {
       CHECK_INTERFACE(IBluetooth, data, reply);
-      bool result = Enable();
+      bool start_restricted = data.readBool();
+      bool result = Enable(start_restricted);
       reply->writeInt32(result);
       return android::NO_ERROR;
     }
@@ -182,10 +183,11 @@ int BpBluetooth::GetState() {
   return reply.readInt32();
 }
 
-bool BpBluetooth::Enable() {
+bool BpBluetooth::Enable(bool start_restricted) {
   Parcel data, reply;
 
   data.writeInterfaceToken(IBluetooth::getInterfaceDescriptor());
+  data.writeBool(start_restricted);
   remote()->transact(IBluetooth::ENABLE_TRANSACTION, data, &reply);
 
   return reply.readInt32();
index 54e0b19..ad1d33c 100644 (file)
@@ -134,7 +134,7 @@ class IBluetooth : public android::IInterface {
 
   virtual bool IsEnabled() = 0;
   virtual int GetState() = 0;
-  virtual bool Enable() = 0;
+  virtual bool Enable(bool start_restricted) = 0;
   virtual bool EnableNoAutoConnect() = 0;
   virtual bool Disable() = 0;
 
@@ -184,7 +184,7 @@ class BpBluetooth : public android::BpInterface<IBluetooth> {
   // IBluetooth overrides:
   bool IsEnabled() override;
   int GetState() override;
-  bool Enable() override;
+  bool Enable(bool start_restricted) override;
   bool EnableNoAutoConnect() override;
   bool Disable() override;
 
index a0b4eaa..5036c63 100644 (file)
@@ -23,7 +23,7 @@ namespace {
 
 FakeBluetoothInterface::Manager g_hal_manager;
 
-int FakeHALEnable() {
+int FakeHALEnable(bool start_restricted) {
   return g_hal_manager.enable_succeed ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
index 7b216ca..198ccf6 100644 (file)
@@ -50,9 +50,9 @@ int BluetoothBinderServer::GetState() {
   return adapter_->GetState();
 }
 
-bool BluetoothBinderServer::Enable() {
+bool BluetoothBinderServer::Enable(bool start_restricted) {
   VLOG(2) << __func__;
-  return adapter_->Enable();
+  return adapter_->Enable(start_restricted);
 }
 
 bool BluetoothBinderServer::EnableNoAutoConnect() {
index 4c85a2d..351a858 100644 (file)
@@ -45,7 +45,7 @@ class BluetoothBinderServer : public BnBluetooth,
   // IBluetooth overrides:
   bool IsEnabled() override;
   int GetState() override;
-  bool Enable() override;
+  bool Enable(bool start_restricted) override;
   bool EnableNoAutoConnect() override;
   bool Disable() override;
 
@@ -65,7 +65,6 @@ class BluetoothBinderServer : public BnBluetooth,
   android::sp<IBluetoothGattServer> GetGattServerInterface() override;
 
   android::status_t dump(int fd, const android::Vector<android::String16>& args) override;
-
   // bluetooth::Adapter::Observer overrides:
   void OnAdapterStateChanged(bluetooth::Adapter* adapter,
                              bluetooth::AdapterState prev_state,
index 1c2df52..1d094a4 100644 (file)
@@ -127,12 +127,12 @@ TEST_F(AdapterTest, Enable) {
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
 
   // Enable fails at HAL level
-  EXPECT_FALSE(adapter_->Enable());
+  EXPECT_FALSE(adapter_->Enable(false));
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
 
   // Enable success
   fake_hal_manager_->enable_succeed = true;
-  EXPECT_TRUE(adapter_->Enable());
+  EXPECT_TRUE(adapter_->Enable(false));
 
   // Should have received a state update.
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state());
@@ -140,7 +140,7 @@ TEST_F(AdapterTest, Enable) {
 
   // Enable fails because not disabled
   EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, adapter_->GetState());
-  EXPECT_FALSE(adapter_->Enable());
+  EXPECT_FALSE(adapter_->Enable(false));
 
   // Adapter state updates properly
   fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
@@ -151,7 +151,7 @@ TEST_F(AdapterTest, Enable) {
   EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
 
   // Enable fails because already enabled
-  EXPECT_FALSE(adapter_->Enable());
+  EXPECT_FALSE(adapter_->Enable(false));
 }
 
 TEST_F(AdapterTest, Disable) {
index d46ea03..b561926 100644 (file)
@@ -32,7 +32,7 @@ class MockAdapter : public Adapter {
   MOCK_METHOD1(RemoveObserver, void(Observer*));
   MOCK_CONST_METHOD0(GetState, AdapterState());
   MOCK_CONST_METHOD0(IsEnabled, bool());
-  MOCK_METHOD0(Enable, bool());
+  MOCK_METHOD1(Enable, bool(bool));
   MOCK_METHOD0(Disable, bool());
   MOCK_CONST_METHOD0(GetName, std::string());
   MOCK_METHOD1(SetName, bool(const std::string&));
index d2bf0fa..1f78b21 100644 (file)
@@ -38,7 +38,7 @@ TEST_F(BluetoothTest, AdapterEnableDisable) {
   EXPECT_EQ(GetState(), BT_STATE_OFF) <<
     "Test should be run with Adapter disabled";
 
-  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON) <<  "Adapter did not turn on.";
 
@@ -52,7 +52,7 @@ TEST_F(BluetoothTest, AdapterRepeatedEnableDisable) {
     << "Test should be run with Adapter disabled";
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+    EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) <<  "Adapter did not turn on.";
 
@@ -65,7 +65,7 @@ TEST_F(BluetoothTest, AdapterRepeatedEnableDisable) {
 TEST_F(BluetoothTest, AdapterSetGetName) {
   bt_property_t *new_name = property_new_name("BluetoothTestName1");
 
-  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
     << "Test should be run with Adapter enabled";
@@ -115,7 +115,7 @@ TEST_F(BluetoothTest, AdapterSetGetName) {
 }
 
 TEST_F(BluetoothTest, AdapterStartDiscovery) {
-  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
     << "Test should be run with Adapter enabled";
@@ -131,7 +131,7 @@ TEST_F(BluetoothTest, AdapterStartDiscovery) {
 }
 
 TEST_F(BluetoothTest, AdapterCancelDiscovery) {
-  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
     << "Test should be run with Adapter enabled";
@@ -156,7 +156,7 @@ TEST_F(BluetoothTest, AdapterDisableDuringBonding) {
   bt_bdaddr_t bdaddr = { { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 } };
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+    EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) <<  "Adapter did not turn on.";
 
index 1506247..a7912bb 100644 (file)
@@ -37,7 +37,7 @@ void GattTest::SetUp() {
   status_ = 0;
 
   BluetoothTest::SetUp();
-  ASSERT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
+  ASSERT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_TRUE(GetState() == BT_STATE_ON);