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

Commit 97111a7a authored by Wei Wang's avatar Wei Wang Committed by android-build-merger
Browse files

Merge "Disallow duplicate listeners for WifiScanner." into mm-wireless-dev am: 3c0d65de

am: f89786f3

* commit 'f89786f3':
  Disallow duplicate listeners for WifiScanner.
parents 39d87140 f89786f3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26830,6 +26830,7 @@ package android.net.wifi {
    method public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
    field public static final int MAX_SCAN_PERIOD_MS = 1024000; // 0xfa000
    field public static final int MIN_SCAN_PERIOD_MS = 1000; // 0x3e8
    field public static final int REASON_DUPLICATE_REQEUST = -5; // 0xfffffffb
    field public static final int REASON_INVALID_LISTENER = -2; // 0xfffffffe
    field public static final int REASON_INVALID_REQUEST = -3; // 0xfffffffd
    field public static final int REASON_NOT_AUTHORIZED = -4; // 0xfffffffc
+97 −20
Original line number Diff line number Diff line
@@ -30,7 +30,9 @@ import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;

import java.util.List;
@@ -78,6 +80,8 @@ public class WifiScanner {
    public static final int REASON_INVALID_REQUEST = -3;
    /** Invalid request */
    public static final int REASON_NOT_AUTHORIZED = -4;
    /** An outstanding request with the same listener hasn't finished yet. */
    public static final int REASON_DUPLICATE_REQEUST = -5;

    /** @hide */
    public static final String GET_AVAILABLE_CHANNELS_EXTRA = "Channels";
@@ -460,8 +464,11 @@ public class WifiScanner {
     *                 scans should also not share this object.
     */
    public void startBackgroundScan(ScanSettings settings, ScanListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = addListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, putListener(listener), settings);
        sAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, key, settings);
    }
    /**
     * stop an ongoing wifi scan
@@ -469,8 +476,11 @@ public class WifiScanner {
     *  #startBackgroundScan}
     */
    public void stopBackgroundScan(ScanListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = removeListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_STOP_BACKGROUND_SCAN, 0, removeListener(listener));
        sAsyncChannel.sendMessage(CMD_STOP_BACKGROUND_SCAN, 0, key);
    }
    /**
     * reports currently available scan results on appropriate listeners
@@ -491,8 +501,11 @@ public class WifiScanner {
     *                 scans should also not share this object.
     */
    public void startScan(ScanSettings settings, ScanListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = addListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, putListener(listener), settings);
        sAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, settings);
    }

    /**
@@ -501,8 +514,11 @@ public class WifiScanner {
     * @param listener
     */
    public void stopScan(ScanListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = removeListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, removeListener(listener));
        sAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, key);
    }

    /** specifies information about an access point of interest */
@@ -634,8 +650,11 @@ public class WifiScanner {
     *                 provided on {@link #stopTrackingWifiChange}
     */
    public void startTrackingWifiChange(WifiChangeListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = addListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_START_TRACKING_CHANGE, 0, putListener(listener));
        sAsyncChannel.sendMessage(CMD_START_TRACKING_CHANGE, 0, key);
    }

    /**
@@ -644,8 +663,10 @@ public class WifiScanner {
     * #stopTrackingWifiChange}
     */
    public void stopTrackingWifiChange(WifiChangeListener listener) {
        int key = removeListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_STOP_TRACKING_CHANGE, 0, removeListener(listener));
        sAsyncChannel.sendMessage(CMD_STOP_TRACKING_CHANGE, 0, key);
    }

    /** @hide */
@@ -730,11 +751,14 @@ public class WifiScanner {
     */
    public void startTrackingBssids(BssidInfo[] bssidInfos,
                                    int apLostThreshold, BssidListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = addListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        HotlistSettings settings = new HotlistSettings();
        settings.bssidInfos = bssidInfos;
        settings.apLostThreshold = apLostThreshold;
        sAsyncChannel.sendMessage(CMD_SET_HOTLIST, 0, putListener(listener), settings);
        sAsyncChannel.sendMessage(CMD_SET_HOTLIST, 0, key, settings);
    }

    /**
@@ -742,8 +766,11 @@ public class WifiScanner {
     * @param listener same object provided in {@link #startTrackingBssids}
     */
    public void stopTrackingBssids(BssidListener listener) {
        Preconditions.checkNotNull(listener, "listener cannot be null");
        int key = removeListener(listener);
        if (key == INVALID_KEY) return;
        validateChannel();
        sAsyncChannel.sendMessage(CMD_RESET_HOTLIST, 0, removeListener(listener));
        sAsyncChannel.sendMessage(CMD_RESET_HOTLIST, 0, key);
    }


@@ -812,7 +839,7 @@ public class WifiScanner {

    private static final Object sThreadRefLock = new Object();
    private static int sThreadRefCount;
    private static HandlerThread sHandlerThread;
    private static Handler sInternalHandler;

    /**
     * Create a new WifiScanner instance.
@@ -824,12 +851,29 @@ public class WifiScanner {
     * @hide
     */
    public WifiScanner(Context context, IWifiScanner service) {
        this(context, service, null, true);
    }

    /**
     * Create a new WifiScanner instance.
     *
     * @param context The application context.
     * @param service The IWifiScanner Binder interface
     * @param looper Looper for running WifiScanner operations. If null, a handler thread will be
     *          created for running WifiScanner operations.
     * @param waitForConnection If true, this will not return until a connection to Wifi Scanner
     *          service is established.
     * @hide
     */
    @VisibleForTesting
    public WifiScanner(Context context, IWifiScanner service, Looper looper,
            boolean waitForConnection) {
        mContext = context;
        mService = service;
        init();
        init(looper, waitForConnection);
    }

    private void init() {
    private void init(Looper looper, boolean waitForConnection) {
        synchronized (sThreadRefLock) {
            if (++sThreadRefCount == 1) {
                Messenger messenger = null;
@@ -846,13 +890,18 @@ public class WifiScanner {
                    return;
                }

                sHandlerThread = new HandlerThread("WifiScanner");
                sAsyncChannel = new AsyncChannel();
                sConnected = new CountDownLatch(1);

                sHandlerThread.start();
                Handler handler = new ServiceHandler(sHandlerThread.getLooper());
                sAsyncChannel.connect(mContext, handler, messenger);
                if (looper == null) {
                    HandlerThread thread = new HandlerThread("WifiScanner");
                    thread.start();
                    sInternalHandler = new ServiceHandler(thread.getLooper());
                } else {
                    sInternalHandler = new ServiceHandler(looper);
                }
                sAsyncChannel.connect(mContext, sInternalHandler, messenger);
                if (waitForConnection) {
                    try {
                        sConnected.await();
                    } catch (InterruptedException e) {
@@ -861,12 +910,37 @@ public class WifiScanner {
                }
            }
        }
    }

    private void validateChannel() {
        if (sAsyncChannel == null) throw new IllegalStateException(
                "No permission to access and change wifi or a bad initialization");
    }

    // Add a listener into listener map. If the listener already exists, return INVALID_KEY and
    // send an error message to internal handler; Otherwise add the listener to the listener map and
    // return the key of the listener.
    private int addListener(ActionListener listener) {
        synchronized (sListenerMap) {
            boolean keyExists = (getListenerKey(listener) != INVALID_KEY);
            // Note we need to put the listener into listener map even if it's a duplicate as the
            // internal handler will need the key to find the listener. In case of duplicates,
            // removing duplicate key logic will be handled in internal handler.
            int key = putListener(listener);
            if (keyExists) {
                if (DBG) Log.d(TAG, "listener key already exists");
                OperationResult operationResult = new OperationResult(REASON_DUPLICATE_REQEUST,
                        "Outstanding request with same key not stopped yet");
                Message message = Message.obtain(sInternalHandler, CMD_OP_FAILED, 0, key,
                        operationResult);
                message.sendToTarget();
                return INVALID_KEY;
            } else {
                return key;
            }
        }
    }

    private static int putListener(Object listener) {
        if (listener == null) return INVALID_KEY;
        int key;
@@ -910,7 +984,10 @@ public class WifiScanner {

    private static int removeListener(Object listener) {
        int key = getListenerKey(listener);
        if (key == INVALID_KEY) return key;
        if (key == INVALID_KEY) {
            Log.e(TAG, "listener cannot be found");
            return key;
        }
        synchronized (sListenerMapLock) {
            sListenerMap.remove(key);
            return key;