Merge "Use ConnectivityThread for RttManager." into nyc-dev
This commit is contained in:
@@ -542,7 +542,8 @@ final class SystemServiceRegistry {
|
|||||||
public RttManager createService(ContextImpl ctx) {
|
public RttManager createService(ContextImpl ctx) {
|
||||||
IBinder b = ServiceManager.getService(Context.WIFI_RTT_SERVICE);
|
IBinder b = ServiceManager.getService(Context.WIFI_RTT_SERVICE);
|
||||||
IRttManager service = IRttManager.Stub.asInterface(b);
|
IRttManager service = IRttManager.Stub.asInterface(b);
|
||||||
return new RttManager(ctx.getOuterContext(), service);
|
return new RttManager(ctx.getOuterContext(), service,
|
||||||
|
ConnectivityThread.getInstanceLooper());
|
||||||
}});
|
}});
|
||||||
|
|
||||||
registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
|
registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.annotation.SystemApi;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
@@ -19,8 +18,6 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.util.AsyncChannel;
|
import com.android.internal.util.AsyncChannel;
|
||||||
import com.android.internal.util.Protocol;
|
import com.android.internal.util.Protocol;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public class RttManager {
|
public class RttManager {
|
||||||
@@ -311,7 +308,7 @@ public class RttManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RttCapabilities getRttCapabilities() {
|
public RttCapabilities getRttCapabilities() {
|
||||||
synchronized (sCapabilitiesLock) {
|
synchronized (mCapabilitiesLock) {
|
||||||
if (mRttCapabilities == null) {
|
if (mRttCapabilities == null) {
|
||||||
try {
|
try {
|
||||||
mRttCapabilities = mService.getRttCapabilities();
|
mRttCapabilities = mService.getRttCapabilities();
|
||||||
@@ -932,13 +929,13 @@ public class RttManager {
|
|||||||
validateChannel();
|
validateChannel();
|
||||||
ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
|
ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
|
||||||
Log.i(TAG, "Send RTT request to RTT Service");
|
Log.i(TAG, "Send RTT request to RTT Service");
|
||||||
sAsyncChannel.sendMessage(CMD_OP_START_RANGING,
|
mAsyncChannel.sendMessage(CMD_OP_START_RANGING,
|
||||||
0, putListener(listener), parcelableParams);
|
0, putListener(listener), parcelableParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopRanging(RttListener listener) {
|
public void stopRanging(RttListener listener) {
|
||||||
validateChannel();
|
validateChannel();
|
||||||
sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
|
mAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -975,7 +972,7 @@ public class RttManager {
|
|||||||
}
|
}
|
||||||
validateChannel();
|
validateChannel();
|
||||||
int key = putListenerIfAbsent(callback);
|
int key = putListenerIfAbsent(callback);
|
||||||
sAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
|
mAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -998,7 +995,7 @@ public class RttManager {
|
|||||||
Log.e(TAG, "responder not enabled yet");
|
Log.e(TAG, "responder not enabled yet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
|
mAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1110,23 +1107,17 @@ public class RttManager {
|
|||||||
public static final int
|
public static final int
|
||||||
CMD_OP_ENALBE_RESPONDER_FAILED = BASE + 8;
|
CMD_OP_ENALBE_RESPONDER_FAILED = BASE + 8;
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private IRttManager mService;
|
|
||||||
private RttCapabilities mRttCapabilities;
|
|
||||||
|
|
||||||
private static final int INVALID_KEY = 0;
|
private static final int INVALID_KEY = 0;
|
||||||
private static int sListenerKey = 1;
|
|
||||||
|
|
||||||
private static final SparseArray sListenerMap = new SparseArray();
|
private final Context mContext;
|
||||||
private static final Object sListenerMapLock = new Object();
|
private final IRttManager mService;
|
||||||
private static final Object sCapabilitiesLock = new Object();
|
private final SparseArray mListenerMap = new SparseArray();
|
||||||
|
private final Object mListenerMapLock = new Object();
|
||||||
|
private final Object mCapabilitiesLock = new Object();
|
||||||
|
|
||||||
private static AsyncChannel sAsyncChannel;
|
private RttCapabilities mRttCapabilities;
|
||||||
private static CountDownLatch sConnected;
|
private int mListenerKey = 1;
|
||||||
|
private AsyncChannel mAsyncChannel;
|
||||||
private static final Object sThreadRefLock = new Object();
|
|
||||||
private static int sThreadRefCount;
|
|
||||||
private static HandlerThread sHandlerThread;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new WifiScanner instance.
|
* Create a new WifiScanner instance.
|
||||||
@@ -1135,122 +1126,107 @@ public class RttManager {
|
|||||||
* the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
|
* the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
|
||||||
* @param context the application context
|
* @param context the application context
|
||||||
* @param service the Binder interface
|
* @param service the Binder interface
|
||||||
|
* @param looper Looper for running the callbacks.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
public RttManager(Context context, IRttManager service, Looper looper) {
|
||||||
public RttManager(Context context, IRttManager service) {
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mService = service;
|
mService = service;
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
synchronized (sThreadRefLock) {
|
|
||||||
if (++sThreadRefCount == 1) {
|
|
||||||
Messenger messenger = null;
|
Messenger messenger = null;
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "Get the messenger from " + mService);
|
Log.d(TAG, "Get the messenger from " + mService);
|
||||||
messenger = mService.getMessenger();
|
messenger = mService.getMessenger();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
} catch (SecurityException e) {
|
|
||||||
/* do nothing */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messenger == null) {
|
if (messenger == null) {
|
||||||
sAsyncChannel = null;
|
throw new IllegalStateException("getMessenger() returned null! This is invalid.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sHandlerThread = new HandlerThread("RttManager");
|
mAsyncChannel = new AsyncChannel();
|
||||||
sAsyncChannel = new AsyncChannel();
|
|
||||||
sConnected = new CountDownLatch(1);
|
|
||||||
|
|
||||||
sHandlerThread.start();
|
Handler handler = new ServiceHandler(looper);
|
||||||
Handler handler = new ServiceHandler(sHandlerThread.getLooper());
|
mAsyncChannel.connectSync(mContext, handler, messenger);
|
||||||
sAsyncChannel.connect(mContext, handler, messenger);
|
// We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
|
||||||
try {
|
// synchronously, which causes RttService to receive the wrong replyTo value.
|
||||||
sConnected.await();
|
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.e(TAG, "interrupted wait at init");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateChannel() {
|
private void validateChannel() {
|
||||||
if (sAsyncChannel == null) throw new IllegalStateException(
|
if (mAsyncChannel == null) throw new IllegalStateException(
|
||||||
"No permission to access and change wifi or a bad initialization");
|
"No permission to access and change wifi or a bad initialization");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int putListener(Object listener) {
|
private int putListener(Object listener) {
|
||||||
if (listener == null) return INVALID_KEY;
|
if (listener == null) return INVALID_KEY;
|
||||||
int key;
|
int key;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
do {
|
do {
|
||||||
key = sListenerKey++;
|
key = mListenerKey++;
|
||||||
} while (key == INVALID_KEY);
|
} while (key == INVALID_KEY);
|
||||||
sListenerMap.put(key, listener);
|
mListenerMap.put(key, listener);
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a listener if it doesn't exist in sListenerMap. Returns the key of the listener.
|
// Insert a listener if it doesn't exist in mListenerMap. Returns the key of the listener.
|
||||||
private static int putListenerIfAbsent(Object listener) {
|
private int putListenerIfAbsent(Object listener) {
|
||||||
if (listener == null) return INVALID_KEY;
|
if (listener == null) return INVALID_KEY;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
int key = getListenerKey(listener);
|
int key = getListenerKey(listener);
|
||||||
if (key != INVALID_KEY) {
|
if (key != INVALID_KEY) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
key = sListenerKey++;
|
key = mListenerKey++;
|
||||||
} while (key == INVALID_KEY);
|
} while (key == INVALID_KEY);
|
||||||
sListenerMap.put(key, listener);
|
mListenerMap.put(key, listener);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object getListener(int key) {
|
private Object getListener(int key) {
|
||||||
if (key == INVALID_KEY) return null;
|
if (key == INVALID_KEY) return null;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
Object listener = sListenerMap.get(key);
|
Object listener = mListenerMap.get(key);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getListenerKey(Object listener) {
|
private int getListenerKey(Object listener) {
|
||||||
if (listener == null) return INVALID_KEY;
|
if (listener == null) return INVALID_KEY;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
int index = sListenerMap.indexOfValue(listener);
|
int index = mListenerMap.indexOfValue(listener);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return INVALID_KEY;
|
return INVALID_KEY;
|
||||||
} else {
|
} else {
|
||||||
return sListenerMap.keyAt(index);
|
return mListenerMap.keyAt(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object removeListener(int key) {
|
private Object removeListener(int key) {
|
||||||
if (key == INVALID_KEY) return null;
|
if (key == INVALID_KEY) return null;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
Object listener = sListenerMap.get(key);
|
Object listener = mListenerMap.get(key);
|
||||||
sListenerMap.remove(key);
|
mListenerMap.remove(key);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int removeListener(Object listener) {
|
private int removeListener(Object listener) {
|
||||||
int key = getListenerKey(listener);
|
int key = getListenerKey(listener);
|
||||||
if (key == INVALID_KEY) return key;
|
if (key == INVALID_KEY) return key;
|
||||||
synchronized (sListenerMapLock) {
|
synchronized (mListenerMapLock) {
|
||||||
sListenerMap.remove(key);
|
mListenerMap.remove(key);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ServiceHandler extends Handler {
|
private class ServiceHandler extends Handler {
|
||||||
ServiceHandler(Looper looper) {
|
ServiceHandler(Looper looper) {
|
||||||
super(looper);
|
super(looper);
|
||||||
}
|
}
|
||||||
@@ -1258,24 +1234,13 @@ public class RttManager {
|
|||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
Log.i(TAG, "RTT manager get message: " + msg.what);
|
Log.i(TAG, "RTT manager get message: " + msg.what);
|
||||||
switch (msg.what) {
|
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;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
|
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
|
||||||
sConnected.countDown();
|
|
||||||
return;
|
return;
|
||||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
|
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
|
||||||
Log.e(TAG, "Channel connection lost");
|
Log.e(TAG, "Channel connection lost");
|
||||||
// This will cause all further async API calls on the WifiManager
|
// This will cause all further async API calls on the WifiManager
|
||||||
// to fail and throw an exception
|
// to fail and throw an exception
|
||||||
sAsyncChannel = null;
|
mAsyncChannel = null;
|
||||||
getLooper().quit();
|
getLooper().quit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user