Offload config save functionality to BTIF thread

Offload config save functionality to btif thread from
timer thread as timer callback thread is critical in
a2dp playback case.

If the timer callback thread is busy in config save due
to IO operations, it may lead to a2dp audio choppy.

Fix to avoid the "bt_config.conf" file corruption from
the file system. This will avoid losing the paired
information in some corner case, such as abrupt power
off and on. This patch will ensure bt_config is saved to

Bug: 24875861
CRs-Fixed: 953993
Change-Id: I893e9afefa89cbab6e7ddd8835ca77d3e316874c
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
index dfd308e..b9a6e83 100644
--- a/btif/src/btif_config.c
+++ b/btif/src/btif_config.c
@@ -27,6 +27,7 @@
 #include "osi/include/alarm.h"
 #include "osi/include/allocator.h"
 #include "btcore/include/bdaddr.h"
+#include "btif_common.h"
 #include "btif_config.h"
 #include "btif_config_transcode.h"
 #include "btif_util.h"
@@ -43,7 +44,7 @@
 static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
 static void timer_config_save_cb(void *data);
-static void btif_config_write(void);
+static void btif_config_write(UINT16 event, char *p_param);
 static void btif_config_devcache_cleanup(void);
 // TODO(zachoverflow): Move these two functions out, because they are too specific for this file
@@ -358,8 +359,11 @@
   assert(alarm_timer != NULL);
+  btif_config_write(0, NULL);
-  btif_config_write();
+  pthread_mutex_lock(&lock);
+  config_save(config, CONFIG_FILE_PATH);
+  pthread_mutex_unlock(&lock);
 int btif_config_clear(void){
@@ -383,10 +387,13 @@
 static void timer_config_save_cb(UNUSED_ATTR void *data) {
-  btif_config_write();
+  // Moving file I/O to btif context instead of timer callback because
+  // it usually takes a lot of time to be completed, introducing
+  // delays during A2DP playback causing blips or choppiness.
+  btif_transfer_context(btif_config_write, 0, NULL, 0, NULL);
-static void btif_config_write(void) {
+static void btif_config_write(UNUSED_ATTR UINT16 event, UNUSED_ATTR char *p_param) {
   assert(config != NULL);
   assert(alarm_timer != NULL);