Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -368,6 +368,7 @@ LOCAL_SRC_FILES += \ wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \ wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \ wifi/java/android/net/wifi/IWifiScanner.aidl \ wifi/java/android/net/wifi/IRttManager.aidl \ packages/services/PacProcessor/com/android/net/IProxyService.aidl \ packages/services/Proxy/com/android/net/IProxyCallback.aidl \ packages/services/Proxy/com/android/net/IProxyPortListener.aidl \ Loading core/java/android/app/ContextImpl.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.app; import android.net.wifi.IWifiScanner; import android.net.wifi.WifiScanner; import android.os.Build; import android.service.persistentdata.IPersistentDataBlockService; Loading Loading @@ -93,6 +91,10 @@ import android.net.wifi.passpoint.IWifiPasspointManager; import android.net.wifi.passpoint.WifiPasspointManager; import android.net.wifi.p2p.IWifiP2pManager; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.IWifiScanner; import android.net.wifi.WifiScanner; import android.net.wifi.IRttManager; import android.net.wifi.RttManager; import android.nfc.NfcManager; import android.os.BatteryManager; import android.os.Binder; Loading Loading @@ -622,6 +624,13 @@ class ContextImpl extends Context { return new WifiScanner(ctx.getOuterContext(), service); }}); registerService(WIFI_RTT_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_RTT_SERVICE); IRttManager service = IRttManager.Stub.asInterface(b); return new RttManager(ctx.getOuterContext(), service); }}); registerService(ETHERNET_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(ETHERNET_SERVICE); Loading core/java/android/content/Context.java +12 −0 Original line number Diff line number Diff line Loading @@ -2067,6 +2067,7 @@ public abstract class Context { WIFI_P2P_SERVICE, WIFI_SCANNING_SERVICE, //@hide: ETHERNET_SERVICE, WIFI_RTT_SERVICE, NSD_SERVICE, AUDIO_SERVICE, MEDIA_ROUTER_SERVICE, Loading Loading @@ -2461,6 +2462,17 @@ public abstract class Context { @SystemApi public static final String WIFI_SCANNING_SERVICE = "wifiscanner"; /** * Use with {@link #getSystemService} to retrieve a {@link * android.net.wifi.RttManager} for ranging devices with wifi * * @see #getSystemService * @see android.net.wifi.RttManager * @hide */ @SystemApi public static final String WIFI_RTT_SERVICE = "rttmanager"; /** * Use with {@link #getSystemService} to retrieve a {@link * android.net.ethernet.EthernetManager} for handling management of Loading wifi/java/android/net/wifi/IRttManager.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.wifi; import android.os.Messenger; /** * {@hide} */ interface IRttManager { Messenger getMessenger(); } wifi/java/android/net/wifi/RttManager.java 0 → 100644 +334 −0 Original line number Diff line number Diff line package android.net.wifi; import android.annotation.SystemApi; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; import com.android.internal.util.AsyncChannel; import java.util.concurrent.CountDownLatch; /** @hide */ @SystemApi public class RttManager { private static final boolean DBG = true; private static final String TAG = "RttManager"; public static final int RTT_TYPE_UNSPECIFIED = 0; public static final int RTT_TYPE_ONE_SIDED = 1; public static final int RTT_TYPE_11_V = 2; public static final int RTT_TYPE_11_MC = 4; public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; public static final int RTT_PEER_TYPE_AP = 1; public static final int RTT_PEER_TYPE_STA = 2; /* requires NAN */ public static final int RTT_CHANNEL_WIDTH_20 = 0; public static final int RTT_CHANNEL_WIDTH_40 = 1; public static final int RTT_CHANNEL_WIDTH_80 = 2; public static final int RTT_CHANNEL_WIDTH_160 = 3; public static final int RTT_CHANNEL_WIDTH_80P80 = 4; public static final int RTT_CHANNEL_WIDTH_5 = 5; public static final int RTT_CHANNEL_WIDTH_10 = 6; public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; public static final int RTT_STATUS_SUCCESS = 0; public static final int RTT_STATUS_FAILURE = 1; public static final int RTT_STATUS_FAIL_NO_RSP = 2; public static final int RTT_STATUS_FAIL_REJECTED = 3; public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; public static final int RTT_STATUS_ABORTED = 8; public static final int REASON_UNSPECIFIED = -1; public static final int REASON_INVALID_LISTENER = -2; public static final int REASON_INVALID_REQUEST = -3; public class Capabilities { int supportedType; int supportedPeerType; } public Capabilities getCapabilities() { return new Capabilities(); } /** specifies parameters for RTT request */ public static class RttParams { /** type of device being ranged; one of RTT_PEER_TYPE_AP or RTT_PEER_TYPE_STA */ public int deviceType; /** type of RTT being sought; one of RTT_TYPE_ONE_SIDED * RTT_TYPE_11_V or RTT_TYPE_11_MC or RTT_TYPE_UNSPECIFIED */ public int requestType; /** mac address of the device being ranged */ public String bssid; /** channel frequency that the device is on; optional */ public int frequency; /** optional channel width. wider channels result in better accuracy, * but they take longer time, and even get aborted may times; use * RTT_CHANNEL_WIDTH_UNSPECIFIED if not specifying */ public int channelWidth; /** number of samples to be taken */ public int num_samples; /** number of retries if a sample fails */ public int num_retries; } /** specifies RTT results */ public static class RttResult { /** mac address of the device being ranged */ public String bssid; /** status of the request */ public int status; /** timestamp of completion, in microsecond since boot */ public long ts; /** average RSSI observed */ public int rssi; /** RSSI spread (i.e. max - min) */ public int rssi_spread; /** average transmit rate */ public int tx_rate; /** average round trip time in nano second */ public long rtt_ns; /** standard deviation observed in round trip time */ public long rtt_sd_ns; /** spread (i.e. max - min) round trip time */ public long rtt_spread_ns; /** average distance in centimeter, computed based on rtt_ns */ public long distance_cm; /** standard deviation observed in distance */ public long distance_sd_cm; /** spread (i.e. max - min) distance */ public long distance_spread_cm; } public static interface RttListener { public void onSuccess(RttResult results[]); public void onFailure(int reason, String description); public void onAborted(); } public void startRanging(RttParams params[], RttListener listener) { validateChannel(); sAsyncChannel.sendMessage(CMD_OP_START_RANGING, 0, removeListener(listener), params); } public void stopRanging(RttListener listener) { validateChannel(); sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener)); } /* private methods */ public static final int CMD_OP_START_RANGING = 0; public static final int CMD_OP_STOP_RANGING = 1; public static final int CMD_OP_FAILED = 2; public static final int CMD_OP_SUCCEEDED = 3; public static final int CMD_OP_ABORTED = 4; private Context mContext; private IRttManager mService; private static final int INVALID_KEY = 0; private static int sListenerKey = 1; private static final SparseArray sListenerMap = new SparseArray(); private static final Object sListenerMapLock = new Object(); private static AsyncChannel sAsyncChannel; private static CountDownLatch sConnected; private static final Object sThreadRefLock = new Object(); private static int sThreadRefCount; private static HandlerThread sHandlerThread; /** * Create a new WifiScanner instance. * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * @param context the application context * @param service the Binder interface * @hide */ public RttManager(Context context, IRttManager service) { mContext = context; mService = service; init(); } private void init() { synchronized (sThreadRefLock) { if (++sThreadRefCount == 1) { Messenger messenger = null; try { messenger = mService.getMessenger(); } catch (RemoteException e) { /* do nothing */ } catch (SecurityException e) { /* do nothing */ } if (messenger == null) { sAsyncChannel = null; 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"); } } } } private void validateChannel() { if (sAsyncChannel == null) throw new IllegalStateException( "No permission to access and change wifi or a bad initialization"); } private static int putListener(Object listener) { if (listener == null) return INVALID_KEY; int key; synchronized (sListenerMapLock) { do { key = sListenerKey++; } while (key == INVALID_KEY); sListenerMap.put(key, listener); } return key; } private static Object getListener(int key) { if (key == INVALID_KEY) return null; synchronized (sListenerMapLock) { Object listener = sListenerMap.get(key); return listener; } } private static int getListenerKey(Object listener) { if (listener == null) return INVALID_KEY; synchronized (sListenerMapLock) { int index = sListenerMap.indexOfValue(listener); if (index == -1) { return INVALID_KEY; } else { return sListenerMap.keyAt(index); } } } private static Object removeListener(int key) { if (key == INVALID_KEY) return null; synchronized (sListenerMapLock) { Object listener = sListenerMap.get(key); sListenerMap.remove(key); return listener; } } private static int removeListener(Object listener) { int key = getListenerKey(listener); if (key == INVALID_KEY) return key; synchronized (sListenerMapLock) { sListenerMap.remove(key); return key; } } private static class ServiceHandler extends Handler { ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); } else { Log.e(TAG, "Failed to set up channel connection"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception sAsyncChannel = null; } sConnected.countDown(); return; case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: return; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: Log.e(TAG, "Channel connection lost"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception sAsyncChannel = null; getLooper().quit(); return; } Object listener = getListener(msg.arg2); if (listener == null) { if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2); return; } else { if (DBG) Log.d(TAG, "listener key = " + msg.arg2); } switch (msg.what) { /* ActionListeners grouped together */ case CMD_OP_SUCCEEDED : ((RttListener) listener).onSuccess((RttResult[])msg.obj); break; case CMD_OP_FAILED : ((RttListener) listener).onFailure(msg.arg1, (String)msg.obj); removeListener(msg.arg2); break; case CMD_OP_ABORTED : ((RttListener) listener).onAborted(); removeListener(msg.arg2); break; default: if (DBG) Log.d(TAG, "Ignoring message " + msg.what); return; } } } } Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -368,6 +368,7 @@ LOCAL_SRC_FILES += \ wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \ wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \ wifi/java/android/net/wifi/IWifiScanner.aidl \ wifi/java/android/net/wifi/IRttManager.aidl \ packages/services/PacProcessor/com/android/net/IProxyService.aidl \ packages/services/Proxy/com/android/net/IProxyCallback.aidl \ packages/services/Proxy/com/android/net/IProxyPortListener.aidl \ Loading
core/java/android/app/ContextImpl.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.app; import android.net.wifi.IWifiScanner; import android.net.wifi.WifiScanner; import android.os.Build; import android.service.persistentdata.IPersistentDataBlockService; Loading Loading @@ -93,6 +91,10 @@ import android.net.wifi.passpoint.IWifiPasspointManager; import android.net.wifi.passpoint.WifiPasspointManager; import android.net.wifi.p2p.IWifiP2pManager; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.IWifiScanner; import android.net.wifi.WifiScanner; import android.net.wifi.IRttManager; import android.net.wifi.RttManager; import android.nfc.NfcManager; import android.os.BatteryManager; import android.os.Binder; Loading Loading @@ -622,6 +624,13 @@ class ContextImpl extends Context { return new WifiScanner(ctx.getOuterContext(), service); }}); registerService(WIFI_RTT_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_RTT_SERVICE); IRttManager service = IRttManager.Stub.asInterface(b); return new RttManager(ctx.getOuterContext(), service); }}); registerService(ETHERNET_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(ETHERNET_SERVICE); Loading
core/java/android/content/Context.java +12 −0 Original line number Diff line number Diff line Loading @@ -2067,6 +2067,7 @@ public abstract class Context { WIFI_P2P_SERVICE, WIFI_SCANNING_SERVICE, //@hide: ETHERNET_SERVICE, WIFI_RTT_SERVICE, NSD_SERVICE, AUDIO_SERVICE, MEDIA_ROUTER_SERVICE, Loading Loading @@ -2461,6 +2462,17 @@ public abstract class Context { @SystemApi public static final String WIFI_SCANNING_SERVICE = "wifiscanner"; /** * Use with {@link #getSystemService} to retrieve a {@link * android.net.wifi.RttManager} for ranging devices with wifi * * @see #getSystemService * @see android.net.wifi.RttManager * @hide */ @SystemApi public static final String WIFI_RTT_SERVICE = "rttmanager"; /** * Use with {@link #getSystemService} to retrieve a {@link * android.net.ethernet.EthernetManager} for handling management of Loading
wifi/java/android/net/wifi/IRttManager.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.wifi; import android.os.Messenger; /** * {@hide} */ interface IRttManager { Messenger getMessenger(); }
wifi/java/android/net/wifi/RttManager.java 0 → 100644 +334 −0 Original line number Diff line number Diff line package android.net.wifi; import android.annotation.SystemApi; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; import com.android.internal.util.AsyncChannel; import java.util.concurrent.CountDownLatch; /** @hide */ @SystemApi public class RttManager { private static final boolean DBG = true; private static final String TAG = "RttManager"; public static final int RTT_TYPE_UNSPECIFIED = 0; public static final int RTT_TYPE_ONE_SIDED = 1; public static final int RTT_TYPE_11_V = 2; public static final int RTT_TYPE_11_MC = 4; public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; public static final int RTT_PEER_TYPE_AP = 1; public static final int RTT_PEER_TYPE_STA = 2; /* requires NAN */ public static final int RTT_CHANNEL_WIDTH_20 = 0; public static final int RTT_CHANNEL_WIDTH_40 = 1; public static final int RTT_CHANNEL_WIDTH_80 = 2; public static final int RTT_CHANNEL_WIDTH_160 = 3; public static final int RTT_CHANNEL_WIDTH_80P80 = 4; public static final int RTT_CHANNEL_WIDTH_5 = 5; public static final int RTT_CHANNEL_WIDTH_10 = 6; public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; public static final int RTT_STATUS_SUCCESS = 0; public static final int RTT_STATUS_FAILURE = 1; public static final int RTT_STATUS_FAIL_NO_RSP = 2; public static final int RTT_STATUS_FAIL_REJECTED = 3; public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; public static final int RTT_STATUS_ABORTED = 8; public static final int REASON_UNSPECIFIED = -1; public static final int REASON_INVALID_LISTENER = -2; public static final int REASON_INVALID_REQUEST = -3; public class Capabilities { int supportedType; int supportedPeerType; } public Capabilities getCapabilities() { return new Capabilities(); } /** specifies parameters for RTT request */ public static class RttParams { /** type of device being ranged; one of RTT_PEER_TYPE_AP or RTT_PEER_TYPE_STA */ public int deviceType; /** type of RTT being sought; one of RTT_TYPE_ONE_SIDED * RTT_TYPE_11_V or RTT_TYPE_11_MC or RTT_TYPE_UNSPECIFIED */ public int requestType; /** mac address of the device being ranged */ public String bssid; /** channel frequency that the device is on; optional */ public int frequency; /** optional channel width. wider channels result in better accuracy, * but they take longer time, and even get aborted may times; use * RTT_CHANNEL_WIDTH_UNSPECIFIED if not specifying */ public int channelWidth; /** number of samples to be taken */ public int num_samples; /** number of retries if a sample fails */ public int num_retries; } /** specifies RTT results */ public static class RttResult { /** mac address of the device being ranged */ public String bssid; /** status of the request */ public int status; /** timestamp of completion, in microsecond since boot */ public long ts; /** average RSSI observed */ public int rssi; /** RSSI spread (i.e. max - min) */ public int rssi_spread; /** average transmit rate */ public int tx_rate; /** average round trip time in nano second */ public long rtt_ns; /** standard deviation observed in round trip time */ public long rtt_sd_ns; /** spread (i.e. max - min) round trip time */ public long rtt_spread_ns; /** average distance in centimeter, computed based on rtt_ns */ public long distance_cm; /** standard deviation observed in distance */ public long distance_sd_cm; /** spread (i.e. max - min) distance */ public long distance_spread_cm; } public static interface RttListener { public void onSuccess(RttResult results[]); public void onFailure(int reason, String description); public void onAborted(); } public void startRanging(RttParams params[], RttListener listener) { validateChannel(); sAsyncChannel.sendMessage(CMD_OP_START_RANGING, 0, removeListener(listener), params); } public void stopRanging(RttListener listener) { validateChannel(); sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener)); } /* private methods */ public static final int CMD_OP_START_RANGING = 0; public static final int CMD_OP_STOP_RANGING = 1; public static final int CMD_OP_FAILED = 2; public static final int CMD_OP_SUCCEEDED = 3; public static final int CMD_OP_ABORTED = 4; private Context mContext; private IRttManager mService; private static final int INVALID_KEY = 0; private static int sListenerKey = 1; private static final SparseArray sListenerMap = new SparseArray(); private static final Object sListenerMapLock = new Object(); private static AsyncChannel sAsyncChannel; private static CountDownLatch sConnected; private static final Object sThreadRefLock = new Object(); private static int sThreadRefCount; private static HandlerThread sHandlerThread; /** * Create a new WifiScanner instance. * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * @param context the application context * @param service the Binder interface * @hide */ public RttManager(Context context, IRttManager service) { mContext = context; mService = service; init(); } private void init() { synchronized (sThreadRefLock) { if (++sThreadRefCount == 1) { Messenger messenger = null; try { messenger = mService.getMessenger(); } catch (RemoteException e) { /* do nothing */ } catch (SecurityException e) { /* do nothing */ } if (messenger == null) { sAsyncChannel = null; 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"); } } } } private void validateChannel() { if (sAsyncChannel == null) throw new IllegalStateException( "No permission to access and change wifi or a bad initialization"); } private static int putListener(Object listener) { if (listener == null) return INVALID_KEY; int key; synchronized (sListenerMapLock) { do { key = sListenerKey++; } while (key == INVALID_KEY); sListenerMap.put(key, listener); } return key; } private static Object getListener(int key) { if (key == INVALID_KEY) return null; synchronized (sListenerMapLock) { Object listener = sListenerMap.get(key); return listener; } } private static int getListenerKey(Object listener) { if (listener == null) return INVALID_KEY; synchronized (sListenerMapLock) { int index = sListenerMap.indexOfValue(listener); if (index == -1) { return INVALID_KEY; } else { return sListenerMap.keyAt(index); } } } private static Object removeListener(int key) { if (key == INVALID_KEY) return null; synchronized (sListenerMapLock) { Object listener = sListenerMap.get(key); sListenerMap.remove(key); return listener; } } private static int removeListener(Object listener) { int key = getListenerKey(listener); if (key == INVALID_KEY) return key; synchronized (sListenerMapLock) { sListenerMap.remove(key); return key; } } private static class ServiceHandler extends Handler { ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); } else { Log.e(TAG, "Failed to set up channel connection"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception sAsyncChannel = null; } sConnected.countDown(); return; case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: return; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: Log.e(TAG, "Channel connection lost"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception sAsyncChannel = null; getLooper().quit(); return; } Object listener = getListener(msg.arg2); if (listener == null) { if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2); return; } else { if (DBG) Log.d(TAG, "listener key = " + msg.arg2); } switch (msg.what) { /* ActionListeners grouped together */ case CMD_OP_SUCCEEDED : ((RttListener) listener).onSuccess((RttResult[])msg.obj); break; case CMD_OP_FAILED : ((RttListener) listener).onFailure(msg.arg1, (String)msg.obj); removeListener(msg.arg2); break; case CMD_OP_ABORTED : ((RttListener) listener).onAborted(); removeListener(msg.arg2); break; default: if (DBG) Log.d(TAG, "Ignoring message " + msg.what); return; } } } }