Snap for 7035108 from b6db1a0ceeaf2fc10478989a54d752d64ad5d6d3 to mainline-release

Change-Id: Idebab4bc0c96f69f06fe30960cc100b5b39c7577
diff --git a/src/com/android/bluetooth/gatt/AdvertiseManager.java b/src/com/android/bluetooth/gatt/AdvertiseManager.java
index 85917a4..b76d861 100644
--- a/src/com/android/bluetooth/gatt/AdvertiseManager.java
+++ b/src/com/android/bluetooth/gatt/AdvertiseManager.java
@@ -217,7 +217,7 @@
 
         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
         if (entry == null) {
-            Log.i(TAG, "onOwnAddressRead() - bad advertiserId " + advertiserId);
+            Log.w(TAG, "onOwnAddressRead() - bad advertiserId " + advertiserId);
             return;
         }
 
@@ -226,6 +226,11 @@
     }
 
     void getOwnAddress(int advertiserId) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "getOwnAddress() - bad advertiserId " + advertiserId);
+            return;
+        }
         getOwnAddressNative(advertiserId);
     }
 
@@ -260,37 +265,72 @@
     }
 
     void enableAdvertisingSet(int advertiserId, boolean enable, int duration, int maxExtAdvEvents) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "enableAdvertisingSet() - bad advertiserId " + advertiserId);
+            return;
+        }
         enableAdvertisingSetNative(advertiserId, enable, duration, maxExtAdvEvents);
     }
 
     void setAdvertisingData(int advertiserId, AdvertiseData data) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setAdvertisingData() - bad advertiserId " + advertiserId);
+            return;
+        }
         String deviceName = AdapterService.getAdapterService().getName();
         setAdvertisingDataNative(advertiserId,
                 AdvertiseHelper.advertiseDataToBytes(data, deviceName));
     }
 
     void setScanResponseData(int advertiserId, AdvertiseData data) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setScanResponseData() - bad advertiserId " + advertiserId);
+            return;
+        }
         String deviceName = AdapterService.getAdapterService().getName();
         setScanResponseDataNative(advertiserId,
                 AdvertiseHelper.advertiseDataToBytes(data, deviceName));
     }
 
     void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setAdvertisingParameters() - bad advertiserId " + advertiserId);
+            return;
+        }
         setAdvertisingParametersNative(advertiserId, parameters);
     }
 
     void setPeriodicAdvertisingParameters(int advertiserId,
             PeriodicAdvertisingParameters parameters) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setPeriodicAdvertisingParameters() - bad advertiserId " + advertiserId);
+            return;
+        }
         setPeriodicAdvertisingParametersNative(advertiserId, parameters);
     }
 
     void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setPeriodicAdvertisingData() - bad advertiserId " + advertiserId);
+            return;
+        }
         String deviceName = AdapterService.getAdapterService().getName();
         setPeriodicAdvertisingDataNative(advertiserId,
                 AdvertiseHelper.advertiseDataToBytes(data, deviceName));
     }
 
     void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
+        Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
+        if (entry == null) {
+            Log.w(TAG, "setPeriodicAdvertisingEnable() - bad advertiserId " + advertiserId);
+            return;
+        }
         setPeriodicAdvertisingEnableNative(advertiserId, enable);
     }
 
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 87e6e52..8a792fe 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -1633,6 +1633,15 @@
         mScanManager.callbackDone(clientIf, status);
     }
 
+    ScanClient findBatchScanClientById(int scannerId) {
+        for (ScanClient client : mScanManager.getBatchScanQueue()) {
+            if (client.scannerId == scannerId) {
+                return client;
+            }
+        }
+        return null;
+    }
+
     void onBatchScanReports(int status, int scannerId, int reportType, int numRecords,
             byte[] recordData) throws RemoteException {
         if (DBG) {
@@ -1647,12 +1656,36 @@
             if (app == null) {
                 return;
             }
+
+            ScanClient client = findBatchScanClientById(scannerId);
+            if (client == null) {
+                return;
+            }
+
+            ArrayList<ScanResult> permittedResults;
+            if (hasScanResultPermission(client)) {
+                permittedResults = new ArrayList<ScanResult>(results);
+            } else {
+                permittedResults = new ArrayList<ScanResult>();
+                for (ScanResult scanResult : results) {
+                    for (String associatedDevice : client.associatedDevices) {
+                        if (associatedDevice.equalsIgnoreCase(scanResult.getDevice()
+                                    .getAddress())) {
+                            permittedResults.add(scanResult);
+                        }
+                    }
+                }
+                if (permittedResults.isEmpty()) {
+                    return;
+                }
+            }
+
             if (app.callback != null) {
-                app.callback.onBatchScanResults(new ArrayList<ScanResult>(results));
+                app.callback.onBatchScanResults(permittedResults);
             } else {
                 // PendingIntent based
                 try {
-                    sendResultsByPendingIntent(app.info, new ArrayList<ScanResult>(results),
+                    sendResultsByPendingIntent(app.info, permittedResults,
                             ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                 } catch (PendingIntent.CanceledException e) {
                 }
@@ -1688,13 +1721,31 @@
         if (app == null) {
             return;
         }
+
+        ArrayList<ScanResult> permittedResults;
+        if (hasScanResultPermission(client)) {
+            permittedResults = new ArrayList<ScanResult>(allResults);
+        } else {
+            permittedResults = new ArrayList<ScanResult>();
+            for (ScanResult scanResult : allResults) {
+                for (String associatedDevice : client.associatedDevices) {
+                    if (associatedDevice.equalsIgnoreCase(scanResult.getDevice().getAddress())) {
+                        permittedResults.add(scanResult);
+                    }
+                }
+            }
+            if (permittedResults.isEmpty()) {
+                return;
+            }
+        }
+
         if (client.filters == null || client.filters.isEmpty()) {
-            sendBatchScanResults(app, client, new ArrayList<ScanResult>(allResults));
+            sendBatchScanResults(app, client, permittedResults);
             // TODO: Question to reviewer: Shouldn't there be a return here?
         }
         // Reconstruct the scan results.
         ArrayList<ScanResult> results = new ArrayList<ScanResult>();
-        for (ScanResult scanResult : allResults) {
+        for (ScanResult scanResult : permittedResults) {
             if (matchesFilters(client, scanResult)) {
                 results.add(scanResult);
             }