Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da28f532 authored by Vinay Kalia's avatar Vinay Kalia Committed by android-build-merger
Browse files

Merge "Stop unfiltered BLE scanning on screen off"

am: 258f385b

Change-Id: Ice9cb0dd6c69954f9639115e87353f0d3596793f
parents 902923e1 258f385b
Loading
Loading
Loading
Loading
+45 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,9 @@ import com.android.bluetooth.btservice.BluetoothProto;


    class LastScan {
    class LastScan {
        long duration;
        long duration;
        long suspendDuration;
        long suspendStartTime;
        boolean isSuspended;
        long timestamp;
        long timestamp;
        boolean opportunistic;
        boolean opportunistic;
        boolean timeout;
        boolean timeout;
@@ -67,6 +70,9 @@ import com.android.bluetooth.btservice.BluetoothProto;
            this.filtered = filtered;
            this.filtered = filtered;
            this.results = 0;
            this.results = 0;
            this.scannerId = scannerId;
            this.scannerId = scannerId;
            this.suspendDuration = 0;
            this.suspendStartTime = 0;
            this.isSuspended = false;
        }
        }
    }
    }


@@ -90,6 +96,7 @@ import com.android.bluetooth.btservice.BluetoothProto;
    long maxScanTime = 0;
    long maxScanTime = 0;
    long mScanStartTime = 0;
    long mScanStartTime = 0;
    long mTotalScanTime = 0;
    long mTotalScanTime = 0;
    long mTotalSuspendTime = 0;
    List<LastScan> lastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT);
    List<LastScan> lastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT);
    HashMap<Integer, LastScan> ongoingScans = new HashMap<Integer, LastScan>();
    HashMap<Integer, LastScan> ongoingScans = new HashMap<Integer, LastScan>();
    long startTime = 0;
    long startTime = 0;
@@ -179,6 +186,10 @@ import com.android.bluetooth.btservice.BluetoothProto;
        stopTime = SystemClock.elapsedRealtime();
        stopTime = SystemClock.elapsedRealtime();
        long scanDuration = stopTime - scan.timestamp;
        long scanDuration = stopTime - scan.timestamp;
        scan.duration = scanDuration;
        scan.duration = scanDuration;
        if (scan.isSuspended) {
            scan.suspendDuration += stopTime - scan.suspendStartTime;
            mTotalSuspendTime += scan.suspendDuration;
        }
        ongoingScans.remove(scannerId);
        ongoingScans.remove(scannerId);
        if (lastScans.size() >= NUM_SCAN_DURATIONS_KEPT) {
        if (lastScans.size() >= NUM_SCAN_DURATIONS_KEPT) {
            lastScans.remove(0);
            lastScans.remove(0);
@@ -208,6 +219,26 @@ import com.android.bluetooth.btservice.BluetoothProto;
        }
        }
    }
    }


    synchronized void recordScanSuspend(int scannerId) {
        LastScan scan = getScanFromScannerId(scannerId);
        if (scan == null || scan.isSuspended) {
            return;
        }
        scan.suspendStartTime = SystemClock.elapsedRealtime();
        scan.isSuspended = true;
    }

    synchronized void recordScanResume(int scannerId) {
        LastScan scan = getScanFromScannerId(scannerId);
        if (scan == null || !scan.isSuspended) {
            return;
        }
        scan.isSuspended = false;
        stopTime = SystemClock.elapsedRealtime();
        scan.suspendDuration += stopTime - scan.suspendStartTime;
        mTotalSuspendTime += scan.suspendDuration;
    }

    synchronized void setScanTimeout(int scannerId) {
    synchronized void setScanTimeout(int scannerId) {
        if (!isScanning()) return;
        if (!isScanning()) return;


@@ -299,6 +330,9 @@ import com.android.bluetooth.btservice.BluetoothProto;
                  maxScan + " / " +
                  maxScan + " / " +
                  avgScan + " / " +
                  avgScan + " / " +
                  totalScanTime + "\n");
                  totalScanTime + "\n");
        if (mTotalSuspendTime != 0) {
            sb.append("  Total time suspended             : " + mTotalSuspendTime + "ms\n");
        }
        sb.append("  Total number of results            : " +
        sb.append("  Total number of results            : " +
                  results + "\n");
                  results + "\n");


@@ -319,6 +353,10 @@ import com.android.bluetooth.btservice.BluetoothProto;
                sb.append(scan.results + " results");
                sb.append(scan.results + " results");
                sb.append(" (" + scan.scannerId + ")");
                sb.append(" (" + scan.scannerId + ")");
                sb.append("\n");
                sb.append("\n");
                if (scan.suspendDuration != 0) {
                    sb.append("      └"
                            + " Suspended Time: " + scan.suspendDuration + "ms\n");
                }
            }
            }
        }
        }


@@ -333,9 +371,16 @@ import com.android.bluetooth.btservice.BluetoothProto;
                if (scan.background) sb.append("Back ");
                if (scan.background) sb.append("Back ");
                if (scan.timeout) sb.append("Forced ");
                if (scan.timeout) sb.append("Forced ");
                if (scan.filtered) sb.append("Filter ");
                if (scan.filtered) sb.append("Filter ");
                if (scan.isSuspended) sb.append("Suspended ");
                sb.append(scan.results + " results");
                sb.append(scan.results + " results");
                sb.append(" (" + scan.scannerId + ")");
                sb.append(" (" + scan.scannerId + ")");
                sb.append("\n");
                sb.append("\n");
                if (scan.suspendStartTime != 0) {
                    long duration = scan.suspendDuration
                            + (scan.isSuspended ? (elapsedRt - scan.suspendStartTime) : 0);
                    sb.append("      └"
                            + " Suspended Time: " + duration + "ms\n");
                }
            }
            }
        }
        }


+90 −1
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Looper;
@@ -34,6 +35,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemClock;
import android.util.Log;
import android.util.Log;
import android.view.Display;


import com.android.bluetooth.Utils;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.AdapterService;
@@ -69,7 +71,8 @@ public class ScanManager {
    private static final int MSG_STOP_BLE_SCAN = 1;
    private static final int MSG_STOP_BLE_SCAN = 1;
    private static final int MSG_FLUSH_BATCH_RESULTS = 2;
    private static final int MSG_FLUSH_BATCH_RESULTS = 2;
    private static final int MSG_SCAN_TIMEOUT = 3;
    private static final int MSG_SCAN_TIMEOUT = 3;

    private static final int MSG_SUSPEND_SCANS = 4;
    private static final int MSG_RESUME_SCANS = 5;
    private static final String ACTION_REFRESH_BATCHED_SCAN =
    private static final String ACTION_REFRESH_BATCHED_SCAN =
            "com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN";
            "com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN";


@@ -89,15 +92,22 @@ public class ScanManager {


    private Set<ScanClient> mRegularScanClients;
    private Set<ScanClient> mRegularScanClients;
    private Set<ScanClient> mBatchClients;
    private Set<ScanClient> mBatchClients;
    private Set<ScanClient> mSuspendedScanClients;


    private CountDownLatch mLatch;
    private CountDownLatch mLatch;


    private DisplayManager mDm;

    ScanManager(GattService service) {
    ScanManager(GattService service) {
        mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mSuspendedScanClients =
                Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mService = service;
        mService = service;
        mScanNative = new ScanNative();
        mScanNative = new ScanNative();
        curUsedTrackableAdvertisements = 0;
        curUsedTrackableAdvertisements = 0;
        mDm = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE);
        mDm.registerDisplayListener(mDisplayListener, null);
    }
    }


    void start() {
    void start() {
@@ -109,6 +119,7 @@ public class ScanManager {
    void cleanup() {
    void cleanup() {
        mRegularScanClients.clear();
        mRegularScanClients.clear();
        mBatchClients.clear();
        mBatchClients.clear();
        mSuspendedScanClients.clear();
        mScanNative.cleanup();
        mScanNative.cleanup();


        if (mHandler != null) {
        if (mHandler != null) {
@@ -215,6 +226,12 @@ public class ScanManager {
                case MSG_SCAN_TIMEOUT:
                case MSG_SCAN_TIMEOUT:
                    mScanNative.regularScanTimeout(client);
                    mScanNative.regularScanTimeout(client);
                    break;
                    break;
                case MSG_SUSPEND_SCANS:
                    handleSuspendScans();
                    break;
                case MSG_RESUME_SCANS:
                    handleResumeScans();
                    break;
                default:
                default:
                    // Shouldn't happen.
                    // Shouldn't happen.
                    Log.e(TAG, "received an unkown message : " + msg.what);
                    Log.e(TAG, "received an unkown message : " + msg.what);
@@ -223,6 +240,7 @@ public class ScanManager {


        void handleStartScan(ScanClient client) {
        void handleStartScan(ScanClient client) {
            Utils.enforceAdminPermission(mService);
            Utils.enforceAdminPermission(mService);
            boolean isFiltered = (client.filters != null) && !client.filters.isEmpty();
            if (DBG) Log.d(TAG, "handling starting scan");
            if (DBG) Log.d(TAG, "handling starting scan");


            if (!isScanSupported(client)) {
            if (!isScanSupported(client)) {
@@ -234,6 +252,15 @@ public class ScanManager {
                Log.e(TAG, "Scan already started");
                Log.e(TAG, "Scan already started");
                return;
                return;
            }
            }

            if (!mScanNative.isOpportunisticScanClient(client) && !isScreenOn() && !isFiltered) {
                Log.e(TAG,
                        "Cannot start unfiltered scan in screen-off. This scan will be resumed later: "
                                + client.scannerId);
                mSuspendedScanClients.add(client);
                return;
            }

            // Begin scan operations.
            // Begin scan operations.
            if (isBatchClient(client)) {
            if (isBatchClient(client)) {
                mBatchClients.add(client);
                mBatchClients.add(client);
@@ -258,6 +285,10 @@ public class ScanManager {
            Utils.enforceAdminPermission(mService);
            Utils.enforceAdminPermission(mService);
            if (client == null) return;
            if (client == null) return;


            if (mSuspendedScanClients.contains(client)) {
                mSuspendedScanClients.remove(client);
            }

            if (mRegularScanClients.contains(client)) {
            if (mRegularScanClients.contains(client)) {
                mScanNative.stopRegularScan(client);
                mScanNative.stopRegularScan(client);


@@ -305,6 +336,30 @@ public class ScanManager {
            return settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_ALL_MATCHES &&
            return settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_ALL_MATCHES &&
                    settings.getReportDelayMillis() == 0;
                    settings.getReportDelayMillis() == 0;
        }
        }

        void handleSuspendScans() {
            for (ScanClient client : mRegularScanClients) {
                if (!mScanNative.isOpportunisticScanClient(client)
                        && (client.filters == null || client.filters.isEmpty())) {
                    /*Suspend unfiltered scans*/
                    if (client.stats != null) {
                        client.stats.recordScanSuspend(client.scannerId);
                    }
                    handleStopScan(client);
                    mSuspendedScanClients.add(client);
                }
            }
        }

        void handleResumeScans() {
            for (ScanClient client : mSuspendedScanClients) {
                if (client.stats != null) {
                    client.stats.recordScanResume(client.scannerId);
                }
                handleStartScan(client);
            }
            mSuspendedScanClients.clear();
        }
    }
    }


    /**
    /**
@@ -1163,4 +1218,38 @@ public class ScanManager {


        private native void gattClientReadScanReportsNative(int client_if, int scan_type);
        private native void gattClientReadScanReportsNative(int client_if, int scan_type);
    }
    }

    private boolean isScreenOn() {
        Display[] displays = mDm.getDisplays();

        if (displays == null) {
            return false;
        }

        for (Display display : displays) {
            if (display.getState() == Display.STATE_ON) {
                return true;
            }
        }

        return false;
    }

    private final DisplayManager.DisplayListener mDisplayListener =
            new DisplayManager.DisplayListener() {
                @Override
                public void onDisplayAdded(int displayId) {}

                @Override
                public void onDisplayRemoved(int displayId) {}

                @Override
                public void onDisplayChanged(int displayId) {
                    if (isScreenOn()) {
                        sendMessage(MSG_RESUME_SCANS, null);
                    } else {
                        sendMessage(MSG_SUSPEND_SCANS, null);
                    }
                }
            };
}
}