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

Commit 258f385b authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Stop unfiltered BLE scanning on screen off"

parents 613fc2e8 319aeae6
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ import com.android.bluetooth.btservice.BluetoothProto;

    class LastScan {
        long duration;
        long suspendDuration;
        long suspendStartTime;
        boolean isSuspended;
        long timestamp;
        boolean opportunistic;
        boolean timeout;
@@ -67,6 +70,9 @@ import com.android.bluetooth.btservice.BluetoothProto;
            this.filtered = filtered;
            this.results = 0;
            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 mScanStartTime = 0;
    long mTotalScanTime = 0;
    long mTotalSuspendTime = 0;
    List<LastScan> lastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT);
    HashMap<Integer, LastScan> ongoingScans = new HashMap<Integer, LastScan>();
    long startTime = 0;
@@ -168,6 +175,10 @@ import com.android.bluetooth.btservice.BluetoothProto;
        stopTime = SystemClock.elapsedRealtime();
        long scanDuration = stopTime - scan.timestamp;
        scan.duration = scanDuration;
        if (scan.isSuspended) {
            scan.suspendDuration += stopTime - scan.suspendStartTime;
            mTotalSuspendTime += scan.suspendDuration;
        }
        ongoingScans.remove(scannerId);
        if (lastScans.size() >= NUM_SCAN_DURATIONS_KEPT) {
            lastScans.remove(0);
@@ -194,6 +205,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) {
        if (!isScanning()) return;

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

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

@@ -315,9 +353,16 @@ import com.android.bluetooth.btservice.BluetoothProto;
                if (scan.background) sb.append("Back ");
                if (scan.timeout) sb.append("Forced ");
                if (scan.filtered) sb.append("Filter ");
                if (scan.isSuspended) sb.append("Suspended ");
                sb.append(scan.results + " results");
                sb.append(" (" + scan.scannerId + ")");
                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 Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -34,6 +35,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;

import com.android.bluetooth.Utils;
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_FLUSH_BATCH_RESULTS = 2;
    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 =
            "com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN";

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

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

    private CountDownLatch mLatch;

    private DisplayManager mDm;

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

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

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

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

            if (!isScanSupported(client)) {
@@ -234,6 +252,15 @@ public class ScanManager {
                Log.e(TAG, "Scan already started");
                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.
            if (isBatchClient(client)) {
                mBatchClients.add(client);
@@ -258,6 +285,10 @@ public class ScanManager {
            Utils.enforceAdminPermission(mService);
            if (client == null) return;

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

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

@@ -305,6 +336,30 @@ public class ScanManager {
            return settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_ALL_MATCHES &&
                    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 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);
                    }
                }
            };
}