diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index f0e6e5f1a106d65828d3c5e9d8aea7e49a72a336..9341946f0dad81c28c10eb92cb94339e9d47dfe8 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -999,8 +999,6 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
   uint16_t service = 0xFFFF;
   tSDP_PROTOCOL_ELEM pe;
 
-  tBTA_DM_SEARCH result;
-
   std::vector<Uuid> uuid_list;
 
   if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) ||
@@ -1025,6 +1023,9 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
        * service UUID */
       if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
         /* all GATT based services */
+
+        std::vector<Uuid> gatt_uuids;
+
         do {
           /* find a service record, report it */
           p_sdp_rec =
@@ -1032,16 +1033,23 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
           if (p_sdp_rec) {
             Uuid service_uuid;
             if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
-              /* send result back to app now, one by one */
-              result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
-              strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
-                      BD_NAME_LEN + 1);
-
-              result.disc_ble_res.service = service_uuid;
-              bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
+              gatt_uuids.push_back(service_uuid);
             }
           }
         } while (p_sdp_rec);
+
+        if (!gatt_uuids.empty()) {
+          LOG_INFO("GATT services discovered using SDP");
+
+          // send all result back to app
+          tBTA_DM_SEARCH result;
+          result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
+          strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
+                  BD_NAME_LEN + 1);
+
+          result.disc_ble_res.services = &gatt_uuids;
+          bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
+        }
       } else {
         /* SDP_DB_FULL means some records with the
            required attributes were received */
@@ -1194,7 +1202,46 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
  ******************************************************************************/
 void bta_dm_search_cmpl() {
   bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
-  bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
+
+  uint16_t conn_id = bta_dm_search_cb.conn_id;
+
+  /* no BLE connection, i.e. Classic service discovery end */
+  if (conn_id == GATT_INVALID_CONN_ID) {
+    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
+    return;
+  }
+
+  btgatt_db_element_t* db = NULL;
+  int count = 0;
+  BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);
+
+  if (count == 0) {
+    LOG_INFO("Empty GATT database - no BLE services discovered");
+    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
+    return;
+  }
+
+  std::vector<Uuid> gatt_services;
+
+  for (int i = 0; i < count; i++) {
+    // we process service entries only
+    if (db[i].type == BTGATT_DB_PRIMARY_SERVICE) {
+      gatt_services.push_back(db[i].uuid);
+    }
+  }
+  osi_free(db);
+
+  tBTA_DM_SEARCH result;
+  result.disc_ble_res.services = &gatt_services;
+  result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
+  strlcpy((char*)result.disc_ble_res.bd_name, (char*)bta_dm_search_cb.peer_name,
+          BD_NAME_LEN + 1);
+
+  LOG_INFO("GATT services discovered using LE Transport");
+  // send all result back to app
+  bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
+
+  bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
 }
 
 /*******************************************************************************
@@ -3588,37 +3635,6 @@ static void bta_dm_gattc_register(void) {
   }
 }
 
-/*******************************************************************************
- *
- * Function         bta_dm_gatt_disc_result
- *
- * Description      This function process the GATT service search result.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) {
-  tBTA_DM_SEARCH result;
-
-  /*
-   * This logic will not work for gatt case.  We are checking against the
-   * bluetooth profiles here
-   * just copy the GATTID in raw data field and send it across.
-   */
-
-  LOG_INFO("%s service_id_uuid_len=%zu", __func__,
-           service_id.uuid.GetShortestRepresentationSize());
-  if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
-    /* send result back to app now, one by one */
-    result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
-    strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
-            BD_NAME_LEN + 1);
-    result.disc_ble_res.service = service_id.uuid;
-
-    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
-  }
-}
-
 /*******************************************************************************
  *
  * Function         bta_dm_gatt_disc_complete
@@ -3768,7 +3784,6 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
       break;
 
     case BTA_GATTC_SEARCH_RES_EVT:
-      bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
       break;
 
     case BTA_GATTC_SEARCH_CMPL_EVT:
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index 3c58ea7fd93fcc74deda2e1cb1a26e1e0ebca6ce..cbe9706f852f3b7fef9e09d7ad9ff35e6fddfa9a 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -419,7 +419,8 @@ typedef struct {
 typedef struct {
   RawAddress bd_addr; /* BD address peer device. */
   BD_NAME bd_name;  /* Name of peer device. */
-  bluetooth::Uuid service; /* GATT based Services UUID found on peer device. */
+  std::vector<bluetooth::Uuid>*
+      services; /* GATT based Services UUID found on peer device. */
 } tBTA_DM_DISC_BLE_RES;
 
 /* Union of all search callback structures */
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 13fbae8ee76c62fdd252b7a1d0a094d7057ce73b..9918f9a519b5eb3bc65719a2ae39d9cd65cbb9f1 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -1236,6 +1236,11 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event,
   }
 }
 
+/* Returns true if |uuid| should be passed as device property */
+static bool btif_is_interesting_le_service(bluetooth::Uuid uuid) {
+  return uuid.As16Bit() == UUID_SERVCLASS_LE_HID || uuid == UUID_HEARING_AID;
+}
+
 /*******************************************************************************
  *
  * Function         btif_dm_search_services_evt
@@ -1334,45 +1339,52 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event,
       break;
 
     case BTA_DM_DISC_BLE_RES_EVT: {
-      LOG_VERBOSE("service %s",
-                  p_data->disc_ble_res.service.ToString().c_str());
       int num_properties = 0;
-      if (p_data->disc_ble_res.service.As16Bit() == UUID_SERVCLASS_LE_HID ||
-          p_data->disc_ble_res.service == UUID_HEARING_AID) {
-        LOG_INFO("Found HOGP or HEARING AID UUID");
-        bt_property_t prop[2];
-        bt_status_t ret;
-
-        const auto& arr = p_data->disc_ble_res.service.To128BitBE();
-
-        RawAddress& bd_addr = p_data->disc_ble_res.bd_addr;
-        prop[0].type = BT_PROPERTY_UUIDS;
-        prop[0].val = (void*)arr.data();
-        prop[0].len = Uuid::kNumBytes128;
+      bt_property_t prop[2];
+      std::vector<uint8_t> property_value;
+      int num_uuids = 0;
+
+      for (Uuid uuid : *p_data->disc_ble_res.services) {
+        LOG_VERBOSE("service %s", uuid.ToString().c_str());
+        if (btif_is_interesting_le_service(uuid)) {
+          num_uuids++;
+          auto valAsBe = uuid.To128BitBE();
+          property_value.insert(property_value.end(), valAsBe.begin(),
+                                valAsBe.end());
+        }
+      }
 
-        /* Also write this to the NVRAM */
-        ret = btif_storage_set_remote_device_property(&bd_addr, &prop[0]);
-        ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed",
-                ret);
-        num_properties++;
+      if (num_uuids == 0) {
+        LOG_INFO("No well known BLE services discovered");
+        return;
+      }
 
-        /* Remote name update */
-        if (strnlen((const char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN)) {
-          prop[1].type = BT_PROPERTY_BDNAME;
-          prop[1].val = p_data->disc_ble_res.bd_name;
-          prop[1].len =
-              strnlen((char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN);
+      RawAddress& bd_addr = p_data->disc_ble_res.bd_addr;
+      prop[0].type = BT_PROPERTY_UUIDS;
+      prop[0].val = (void*)property_value.data();
+      prop[0].len = Uuid::kNumBytes128 * num_uuids;
 
-          ret = btif_storage_set_remote_device_property(&bd_addr, &prop[1]);
-          ASSERTC(ret == BT_STATUS_SUCCESS,
-                  "failed to save remote device property", ret);
-          num_properties++;
-        }
+      /* Also write this to the NVRAM */
+      bt_status_t ret =
+          btif_storage_set_remote_device_property(&bd_addr, &prop[0]);
+      ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", ret);
+      num_properties++;
 
-        /* Send the event to the BTIF */
-        invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr,
-                                           num_properties, prop);
+      /* Remote name update */
+      if (strnlen((const char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN)) {
+        prop[1].type = BT_PROPERTY_BDNAME;
+        prop[1].val = p_data->disc_ble_res.bd_name;
+        prop[1].len = strnlen((char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN);
+
+        ret = btif_storage_set_remote_device_property(&bd_addr, &prop[1]);
+        ASSERTC(ret == BT_STATUS_SUCCESS,
+                "failed to save remote device property", ret);
+        num_properties++;
       }
+
+      /* Send the event to the BTIF */
+      invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr,
+                                         num_properties, prop);
     } break;
 
     default: { ASSERTC(0, "unhandled search services event", event); } break;