Merge "Disallow duplicate listeners for WifiScanner." into mm-wireless-dev

This commit is contained in:
Wei Wang
2016-02-23 05:09:38 +00:00
committed by Android Partner Code Review
2 changed files with 100 additions and 22 deletions

View File

@@ -21211,6 +21211,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

View File

@@ -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) {
mContext = context;
mService = service;
init();
this(context, service, null, true);
}
private void init() {
/**
* 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(looper, waitForConnection);
}
private void init(Looper looper, boolean waitForConnection) {
synchronized (sThreadRefLock) {
if (++sThreadRefCount == 1) {
Messenger messenger = null;
@@ -846,17 +890,23 @@ 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);
try {
sConnected.await();
} catch (InterruptedException e) {
Log.e(TAG, "interrupted wait at init");
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) {
Log.e(TAG, "interrupted wait at init");
}
}
}
}
@@ -867,6 +917,30 @@ public class WifiScanner {
"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;