我们有经常碰到蓝牙可见性和扫描模式,蓝牙可见默认设置120s,扫描默认设置可扫描可连接
为什么要这个,看了看网上的
之前有一段时间盛行蓝牙病毒,后来很多厂商都改了蓝牙设置,在需要传东西时会打开2分钟给你搜索,
然后又看不到了,保护手机的。现在安卓系统的都是这样。不打开可见性,别的手机是搜索不到的
==>胡说八道
settings/bluetooth/BluetoothDiscoverableEnabler.java
private void setEnabled(boolean enable) {
if (enable) {
int timeout = getDiscoverableTimeout();
long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout); //here
updateCountdownSummary();
Log.d(TAG, "setEnabled(): enabled = " + enable + "timeout = " + timeout);
if (timeout > 0) {
BluetoothDiscoverableTimeoutReceiver.setDiscoverableAlarm(mContext, endTimestamp);
} else {
BluetoothDiscoverableTimeoutReceiver.cancelDiscoverableAlarm(mContext);
}
} else {
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
BluetoothDiscoverableTimeoutReceiver.cancelDiscoverableAlarm(mContext);
}
}
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
这个东西是设置的函数
然后就跑到bluetooth app上 Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
boolean setScanMode(int mode, int duration) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
setDiscoverableTimeout(duration); // here
int newMode = convertScanModeToHal(mode);
return mAdapterProperties.setScanMode(newMode);
}
setDiscoverableTimeout(duration); 和 mAdapterProperties.setScanMode(newMode);
先看看discoverabletimeout先吧,为啥要120s
还是在bluetooth app
Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
boolean setDiscoverableTimeout(int timeout) {
synchronized (mObject) {
return mService.setAdapterPropertyNative( //here
AbstractionLayer.BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT,
Utils.intToByteArray(timeout));
}
}
调到native去了,jni.so,还挺快的,毕竟上层就是个废物,需要下面去完成的
Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void *) classInitNative},
{"initNative", "()Z", (void *) initNative},
{"cleanupNative", "()V", (void*) cleanupNative},
{"enableNative", "(Z)Z", (void*) enableNative},
{"disableNative", "()Z", (void*) disableNative},
{"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative}, //here
{"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
传到下面去的就是jint type, jbyteArray value这个两个参数 一个是type 另外一个是value
1、 AbstractionLayer.BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT
2、 Utils.intToByteArray(timeout));
static jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
ALOGV("%s:",__FUNCTION__);
jbyte *val;
jboolean result = JNI_FALSE;
if (!sBluetoothInterface) return result;
val = env->GetByteArrayElements(value, NULL);
bt_property_t prop;
prop.type = (bt_property_type_t) type;
prop.len = env->GetArrayLength(value);
prop.val = val;
int ret = sBluetoothInterface->set_adapter_property(&prop); //here
env->ReleaseByteArrayElements(value, val, 0);
result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
return result;
}
}
下去hardware default.so
system/bt/btif/src/bluetooth.c
static const bt_interface_t bluetoothInterface = {
.size = sizeof(bluetoothInterface),
.init = init,
.enable = enable,
.disable = disable,
.cleanup = cleanup,
.get_adapter_properties = get_adapter_properties,
.get_adapter_property = get_adapter_property,
.set_adapter_property = set_adapter_property, //here
看看这个hardware函数
static int set_adapter_property(const bt_property_t *property)
{
/* sanity check */
if (interface_ready() == FALSE)
return BT_STATUS_NOT_READY;
return btif_set_adapter_property(property);
}
再调 system/bt/btif/src/btif_core.c
bt_status_t btif_set_adapter_property(const bt_property_t *property)
{
btif_storage_req_t req;
bt_status_t status = BT_STATUS_SUCCESS;
int storage_req_id = BTIF_CORE_STORAGE_NOTIFY_STATUS; /* default */
char bd_name[BTM_MAX_LOC_BD_NAME_LEN +1];
UINT16 name_len = 0;
BTIF_TRACE_EVENT("btif_set_adapter_property type: %d, len %d, 0x%x",
property->type, property->len, property->val);
if (!btif_is_enabled())
return BT_STATUS_NOT_READY;
switch(property->type)
{
case BT_PROPERTY_BDNAME:
{
name_len = property->len > BTM_MAX_LOC_BD_NAME_LEN ? BTM_MAX_LOC_BD_NAME_LEN:
property->len;
memcpy(bd_name,property->val, name_len);
bd_name[name_len] = '\0';
BTIF_TRACE_EVENT("set property name : %s", (char *)bd_name);
BTA_DmSetDeviceName((char *)bd_name);
storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
#ifdef BLUETOOTH_RTK
btif_config_set_str("Adapter", "Name",(char *)bd_name);
btif_config_flush();
#endif
}
break;
case BT_PROPERTY_ADAPTER_SCAN_MODE:
{
bt_scan_mode_t mode = *(bt_scan_mode_t*)property->val;
tBTA_DM_DISC disc_mode;
tBTA_DM_CONN conn_mode;
switch(mode)
{
case BT_SCAN_MODE_NONE:
disc_mode = BTA_DM_NON_DISC;
conn_mode = BTA_DM_NON_CONN;
break;
case BT_SCAN_MODE_CONNECTABLE:
disc_mode = BTA_DM_NON_DISC;
conn_mode = BTA_DM_CONN;
break;
case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
disc_mode = BTA_DM_GENERAL_DISC;
conn_mode = BTA_DM_CONN;
break;
default:
BTIF_TRACE_ERROR("invalid scan mode (0x%x)", mode);
return BT_STATUS_PARM_INVALID;
}
BTIF_TRACE_EVENT("set property scan mode : %x", mode);
BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
}
break;
case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: //here
{
/* Nothing to do beside store the value in NV. Java
will change the SCAN_MODE property after setting timeout,
if required */
storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
}
break;
case BT_PROPERTY_BDADDR:
case BT_PROPERTY_UUIDS:
case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
/* no write support through HAL, these properties are only populated from BTA events */
status = BT_STATUS_FAIL;
break;
default:
BTIF_TRACE_ERROR("btif_get_adapter_property : invalid type %d",
property->type);
status = BT_STATUS_FAIL;
break;
}
if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION)
{
/* pass on to storage for updating local database */
memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
return btif_transfer_context(execute_storage_request,
storage_req_id,
(char*)&req,
sizeof(btif_storage_req_t)+property->len,
btif_in_storage_request_copy_cb);
}
return status;
}
再看看
case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: //here
{
/* Nothing to do beside store the value in NV. Java
will change the SCAN_MODE property after setting timeout,
if required */
storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
}
break;
这个是什么意思,什么cmd都没有下,看看人家case BT_PROPERTY_BDNAME ,还下了一个BTA_DmSetDeviceName,就是那个0x1c13的cmd去改地址,
不下cmd,那干嘛,啥意思,看看它说的
will change the SCAN_MODE property after setting timeout,
if required */
说:没什么事干,java上面设置超时会修改scan mode的方式,如果需要的话
设置了一个东西
storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE
到下面去看看
if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION)
{
/* pass on to storage for updating local database */
memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
return btif_transfer_context(execute_storage_request,
storage_req_id,
(char*)&req,
sizeof(btif_storage_req_t)+property->len,
btif_in_storage_request_copy_cb);
}
存储到本地数据库当中,所以我们可以在data/misc/bluedroid/bt_config.conf 可以看的到DiscoveryTimeout = 120