summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Pasanen <invisiblek@cyanogenmod.org>2016-12-05 21:27:31 -0600
committerDan Pasanen <invisiblek@cyanogenmod.org>2016-12-06 18:59:23 -0600
commit18e387abcb404900842e977f30e7829ee7835ced (patch)
tree36cdbdab7306e1fe1565555ba7562a4c598995d5
parentef49a42ed6a5b28743fdc04db7cddac2a85eef0a (diff)
parent1c40f9218d815e4e67482fb8913fce6850e4fb1c (diff)
downloadandroid_packages_apps_Bluetooth-18e387abcb404900842e977f30e7829ee7835ced.tar.gz
android_packages_apps_Bluetooth-18e387abcb404900842e977f30e7829ee7835ced.tar.bz2
android_packages_apps_Bluetooth-18e387abcb404900842e977f30e7829ee7835ced.zip
Merge tag 'android-7.1.1_r4' into cm-14.1
Android 7.1.1 release 4 Change-Id: Ia693c9be65c8662f565d79bb20f9788dae1b7d2d
-rw-r--r--jni/com_android_bluetooth_a2dp.cpp7
-rw-r--r--src/com/android/bluetooth/btservice/AdapterService.java23
-rw-r--r--src/com/android/bluetooth/btservice/RemoteDevices.java34
-rw-r--r--src/com/android/bluetooth/btservice/bluetooth.proto3
-rw-r--r--src/com/android/bluetooth/gatt/ContextMap.java16
-rw-r--r--src/com/android/bluetooth/gatt/GattService.java11
-rw-r--r--src/com/android/bluetooth/gatt/ScanManager.java29
-rwxr-xr-xsrc/com/android/bluetooth/map/BluetoothMapContentObserver.java2
-rw-r--r--src/com/android/bluetooth/pbap/BluetoothPbapReceiver.java12
9 files changed, 106 insertions, 31 deletions
diff --git a/jni/com_android_bluetooth_a2dp.cpp b/jni/com_android_bluetooth_a2dp.cpp
index fd286ffcc..7be8f538a 100644
--- a/jni/com_android_bluetooth_a2dp.cpp
+++ b/jni/com_android_bluetooth_a2dp.cpp
@@ -252,7 +252,11 @@ static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections,
env->DeleteGlobalRef(mCallbacksObj);
mCallbacksObj = NULL;
}
- mCallbacksObj = env->NewGlobalRef(object);
+
+ if ((mCallbacksObj = env->NewGlobalRef(object)) == NULL) {
+ ALOGE("Failed to allocate Global Ref for A2DP Callbacks");
+ return;
+ }
pthread_mutex_unlock(&mMutex);
if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks,
@@ -269,7 +273,6 @@ static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections,
pthread_mutex_unlock(&mMutex);
return;
}
-
}
static void cleanupNative(JNIEnv *env, jobject object) {
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 7299fbe00..aca94b2af 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -89,7 +89,8 @@ import android.os.SystemProperties;
public class AdapterService extends Service {
private static final String TAG = "BluetoothAdapterService";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
+ private static final boolean VERBOSE = false;
private static final boolean TRACE_REF = false;
private static final int MIN_ADVT_INSTANCES_FOR_MA = 5;
private static final int MIN_OFFLOADED_FILTERS = 10;
@@ -2665,11 +2666,12 @@ public class AdapterService extends Service {
}
}
- debugLog("energyInfoCallback() status = " + status +
- "tx_time = " + tx_time + "rx_time = " + rx_time +
- "idle_time = " + idle_time + "energy_used = " + energy_used +
- "ctrl_state = " + ctrl_state +
- "traffic = " + Arrays.toString(data));
+ verboseLog("energyInfoCallback() status = " + status +
+ "tx_time = " + tx_time + "rx_time = " + rx_time +
+ "idle_time = " + idle_time +
+ "energy_used = " + energy_used +
+ "ctrl_state = " + ctrl_state +
+ "traffic = " + Arrays.toString(data));
}
private int getIdleCurrentMa() {
@@ -2715,8 +2717,8 @@ public class AdapterService extends Service {
enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
if (args.length > 0) {
- debugLog("dumpsys arguments, check for protobuf output: " +
- TextUtils.join(" ", args));
+ verboseLog("dumpsys arguments, check for protobuf output: "
+ + TextUtils.join(" ", args));
if (args[0].startsWith("--proto")) {
if (args[0].equals("--proto-java-bin")) {
dumpJava(fd);
@@ -2764,6 +2766,7 @@ public class AdapterService extends Service {
private void dumpJava(FileDescriptor fd) {
BluetoothProto.BluetoothLog log = new BluetoothProto.BluetoothLog();
+ log.setNumBondedDevices(getBondedDevices().length);
for (ProfileService profile : mProfiles) {
profile.dumpProto(log);
@@ -2791,6 +2794,10 @@ public class AdapterService extends Service {
if (DBG) Log.d(TAG, msg);
}
+ private void verboseLog(String msg) {
+ if (VERBOSE) Log.v(TAG, msg);
+ }
+
private void errorLog(String msg) {
Log.e(TAG, msg);
}
diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java
index 2545bd493..91df13bcb 100644
--- a/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -30,12 +30,15 @@ import com.android.bluetooth.Utils;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.ArrayList;
import java.util.HashMap;
-
+import java.util.LinkedList;
+import java.util.Queue;
final class RemoteDevices {
private static final boolean DBG = false;
private static final String TAG = "BluetoothRemoteDevices";
+ // Maximum number of device properties to remember
+ private static final int MAX_DEVICE_QUEUE_SIZE = 200;
private static BluetoothAdapter mAdapter;
private static AdapterService mAdapterService;
@@ -46,12 +49,14 @@ final class RemoteDevices {
private static final int MESSAGE_UUID_INTENT = 1;
private HashMap<String, DeviceProperties> mDevices;
+ private Queue<String> mDeviceQueue;
RemoteDevices(AdapterService service) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mAdapterService = service;
mSdpTracker = new ArrayList<BluetoothDevice>();
mDevices = new HashMap<String, DeviceProperties>();
+ mDeviceQueue = new LinkedList<String>();
}
@@ -61,6 +66,9 @@ final class RemoteDevices {
if (mDevices != null)
mDevices.clear();
+
+ if (mDeviceQueue != null)
+ mDeviceQueue.clear();
}
@Override
@@ -89,7 +97,20 @@ final class RemoteDevices {
DeviceProperties prop = new DeviceProperties();
prop.mDevice = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
prop.mAddress = address;
- mDevices.put(Utils.getAddressStringFromByte(address), prop);
+ String key = Utils.getAddressStringFromByte(address);
+ DeviceProperties pv = mDevices.put(key, prop);
+
+ if (pv == null) {
+ mDeviceQueue.offer(key);
+ if (mDeviceQueue.size() > MAX_DEVICE_QUEUE_SIZE) {
+ String deleteKey = mDeviceQueue.poll();
+ for (BluetoothDevice device : mAdapterService.getBondedDevices()) {
+ if (device.getAddress().equals(deleteKey)) return prop;
+ }
+ debugLog("Removing device " + deleteKey + " from property map");
+ mDevices.remove(deleteKey);
+ }
+ }
return prop;
}
}
@@ -243,20 +264,27 @@ final class RemoteDevices {
BluetoothDevice bdDevice = getDevice(address);
DeviceProperties device;
if (bdDevice == null) {
+ debugLog("Added new device property");
device = addDeviceProperties(address);
bdDevice = getDevice(address);
} else {
device = getDeviceProperties(bdDevice);
}
+ if (types.length <= 0) {
+ errorLog("No properties to update");
+ return;
+ }
+
for (int j = 0; j < types.length && device != null; j++) {
type = types[j];
val = values[j];
- if(val.length <= 0)
+ if (val.length <= 0)
errorLog("devicePropertyChangedCallback: bdDevice: " + bdDevice
+ ", value is empty for type: " + type);
else {
synchronized(mObject) {
+ debugLog("Property type: " + type);
switch (type) {
case AbstractionLayer.BT_PROPERTY_BDNAME:
device.mName = new String(val);
diff --git a/src/com/android/bluetooth/btservice/bluetooth.proto b/src/com/android/bluetooth/btservice/bluetooth.proto
index 11311ea58..77ded7807 100644
--- a/src/com/android/bluetooth/btservice/bluetooth.proto
+++ b/src/com/android/bluetooth/btservice/bluetooth.proto
@@ -25,6 +25,9 @@ message BluetoothLog {
// Scan event information.
repeated ScanEvent scan_event = 4;
+
+ // Number of bonded devices.
+ optional int32 num_bonded_devices = 5;
}
// The information about the device.
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index e3044d586..024572792 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -190,6 +190,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
while (i.hasNext()) {
App entry = i.next();
if (entry.id == id) {
+ removeConnectionsByAppId(id);
entry.unlinkToDeath();
entry.appScanStats.isRegistered = false;
i.remove();
@@ -205,7 +206,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
void addConnection(int id, int connId, String address) {
synchronized (mConnections) {
App entry = getById(id);
- if (entry != null){
+ if (entry != null) {
mConnections.add(new Connection(connId, address, id));
}
}
@@ -228,6 +229,19 @@ import com.android.bluetooth.btservice.BluetoothProto;
}
/**
+ * Remove all connections for a given application ID.
+ */
+ void removeConnectionsByAppId(int appId) {
+ Iterator<Connection> i = mConnections.iterator();
+ while (i.hasNext()) {
+ Connection connection = i.next();
+ if (connection.appId == appId) {
+ i.remove();
+ }
+ }
+ }
+
+ /**
* Get an application context by ID.
*/
App getById(int id) {
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 0316b42b2..07cbbd56b 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -237,6 +237,7 @@ public class GattService extends ProfileService {
boolean permissionCheck(int connId, int handle) {
List<BluetoothGattService> db = gattClientDatabases.get(connId);
+ if (db == null) return true;
for (BluetoothGattService service : db) {
for (BluetoothGattCharacteristic characteristic: service.getCharacteristics()) {
@@ -759,7 +760,15 @@ public class GattService extends ProfileService {
void onSearchCompleted(int connId, int status) throws RemoteException {
if (DBG) Log.d(TAG, "onSearchCompleted() - connId=" + connId+ ", status=" + status);
// Gatt DB is ready!
- gattClientGetGattDbNative(connId);
+
+ // This callback was called from the jni_workqueue thread. If we make request to the stack
+ // on the same thread, it might cause deadlock. Schedule request on a new thread instead.
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ gattClientGetGattDbNative(connId);
+ }
+ });
+ t.start();
}
GattDbElement GetSampleGattDbElement() {
diff --git a/src/com/android/bluetooth/gatt/ScanManager.java b/src/com/android/bluetooth/gatt/ScanManager.java
index bb45bf7c9..621359724 100644
--- a/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/src/com/android/bluetooth/gatt/ScanManager.java
@@ -40,11 +40,13 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.internal.app.IBatteryStats;
import java.util.ArrayDeque;
+import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -95,8 +97,8 @@ public class ScanManager {
private CountDownLatch mLatch;
ScanManager(GattService service) {
- mRegularScanClients = new HashSet<ScanClient>();
- mBatchClients = new HashSet<ScanClient>();
+ mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
+ mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
mService = service;
mScanNative = new ScanNative();
curUsedTrackableAdvertisements = 0;
@@ -238,7 +240,7 @@ public class ScanManager {
if (!mScanNative.isOpportunisticScanClient(client)) {
mScanNative.configureRegularScanParams();
- if (!mScanNative.isFirstMatchScanClient(client)) {
+ if (!mScanNative.isExemptFromScanDowngrade(client)) {
Message msg = mHandler.obtainMessage(MSG_SCAN_TIMEOUT);
msg.obj = client;
// Only one timeout message should exist at any time
@@ -261,10 +263,6 @@ public class ScanManager {
if (client == null) return;
if (mRegularScanClients.contains(client)) {
- // The ScanClient passed in just holds the clientIf. We retrieve the real client,
- // which may have workSource set.
- client = mScanNative.getRegularScanClient(client.clientIf);
- if (client == null) return;
mScanNative.stopRegularScan(client);
@@ -278,7 +276,11 @@ public class ScanManager {
// Update BatteryStats with this workload.
try {
- mBatteryStats.noteBleScanStopped(client.workSource);
+ // The ScanClient passed in just holds the clientIf. We retrieve the real client,
+ // which may have workSource set.
+ ScanClient workClient = mScanNative.getRegularScanClient(client.clientIf);
+ if (workClient != null)
+ mBatteryStats.noteBleScanStopped(workClient.workSource);
} catch (RemoteException e) {
/* ignore */
}
@@ -534,6 +536,12 @@ public class ScanManager {
}
}
+ private boolean isExemptFromScanDowngrade(ScanClient client) {
+ return isOpportunisticScanClient(client)
+ || isFirstMatchScanClient(client)
+ || !shouldUseAllPassFilter(client);
+ }
+
private boolean isOpportunisticScanClient(ScanClient client) {
return client.settings.getScanMode() == ScanSettings.SCAN_MODE_OPPORTUNISTIC;
}
@@ -683,8 +691,9 @@ public class ScanManager {
void regularScanTimeout() {
for (ScanClient client : mRegularScanClients) {
- if (!isOpportunisticScanClient(client) && !isFirstMatchScanClient(client)) {
- logd("clientIf set to scan opportunisticly: " + client.clientIf);
+ if (!isExemptFromScanDowngrade(client)) {
+ Log.w(TAG, "Moving scan client to opportunistic (clientIf "
+ + client.clientIf + ")");
setOpportunisticScanClient(client);
client.stats.setScanTimeout();
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index 8465274a8..c70408ccb 100755
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -1194,7 +1194,7 @@ public class BluetoothMapContentObserver {
private void initMsgList() throws RemoteException {
if (V) Log.d(TAG, "initMsgList");
UserManager manager = UserManager.get(mContext);
- if (manager == null || manager.isUserUnlocked()) return;
+ if (manager == null || !manager.isUserUnlocked()) return;
if (mEnableSmsMms) {
HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapReceiver.java b/src/com/android/bluetooth/pbap/BluetoothPbapReceiver.java
index a35ae5659..fbf3778ed 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapReceiver.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapReceiver.java
@@ -42,22 +42,22 @@ public class BluetoothPbapReceiver extends BroadcastReceiver {
private static final String TAG = "BluetoothPbapReceiver";
- private static final boolean V = Log.isLoggable(BluetoothPbapService.LOG_TAG, Log.VERBOSE);
+ private static final boolean D = BluetoothPbapService.DEBUG;
@Override
public void onReceive(Context context, Intent intent) {
- if (V) Log.v(TAG, "PbapReceiver onReceive ");
Intent in = new Intent();
in.putExtras(intent);
in.setClass(context, BluetoothPbapService.class);
String action = intent.getAction();
in.putExtra("action", action);
- Log.i(TAG, "Enter - onReceive for intent:" + action);
+ if (D) Log.d(TAG, "PbapReceiver onReceive action = " + action);
+
boolean startService = true;
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
in.putExtra(BluetoothAdapter.EXTRA_STATE, state);
- Log.i(TAG, "State :" + state);
+ if (D) Log.d(TAG, "state = " + state);
if ((state == BluetoothAdapter.STATE_TURNING_ON)
|| (state == BluetoothAdapter.STATE_OFF)) {
//FIX: We turn on PBAP after BluetoothAdapter.STATE_ON,
@@ -68,11 +68,13 @@ public class BluetoothPbapReceiver extends BroadcastReceiver {
// Don't forward intent unless device has bluetooth and bluetooth is enabled.
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null || !adapter.isEnabled()) {
+ if (D) Log.d(TAG, "BluetoothAdapter is not enabled (" +
+ adapter + "). Would not start service.");
startService = false;
}
}
if (startService) {
- if (V) Log.v(TAG, "Calling start service!!!! with action = " + in.getAction());
+ if (D) Log.d(TAG, "Calling start service with action = " + in.getAction());
context.startService(in);
}
Log.i(TAG, "Exit - onReceive for intent:" + action);