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) {
|
||||
IBinder b = ServiceManager.getService(Context.WIFI_RTT_SERVICE);
|
||||
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,
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
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.Protocol;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/** @hide */
|
||||
@SystemApi
|
||||
public class RttManager {
|
||||
@@ -311,7 +308,7 @@ public class RttManager {
|
||||
}
|
||||
|
||||
public RttCapabilities getRttCapabilities() {
|
||||
synchronized (sCapabilitiesLock) {
|
||||
synchronized (mCapabilitiesLock) {
|
||||
if (mRttCapabilities == null) {
|
||||
try {
|
||||
mRttCapabilities = mService.getRttCapabilities();
|
||||
@@ -932,13 +929,13 @@ public class RttManager {
|
||||
validateChannel();
|
||||
ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
|
||||
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);
|
||||
}
|
||||
|
||||
public void stopRanging(RttListener listener) {
|
||||
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();
|
||||
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");
|
||||
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
|
||||
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 int sListenerKey = 1;
|
||||
|
||||
private static final SparseArray sListenerMap = new SparseArray();
|
||||
private static final Object sListenerMapLock = new Object();
|
||||
private static final Object sCapabilitiesLock = new Object();
|
||||
private final Context mContext;
|
||||
private final IRttManager mService;
|
||||
private final SparseArray mListenerMap = new SparseArray();
|
||||
private final Object mListenerMapLock = new Object();
|
||||
private final Object mCapabilitiesLock = 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;
|
||||
private RttCapabilities mRttCapabilities;
|
||||
private int mListenerKey = 1;
|
||||
private AsyncChannel mAsyncChannel;
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* @param context the application context
|
||||
* @param service the Binder interface
|
||||
* @param looper Looper for running the callbacks.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public RttManager(Context context, IRttManager service) {
|
||||
public RttManager(Context context, IRttManager service, Looper looper) {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
synchronized (sThreadRefLock) {
|
||||
if (++sThreadRefCount == 1) {
|
||||
Messenger messenger = null;
|
||||
try {
|
||||
Log.d(TAG, "Get the messenger from " + mService);
|
||||
messenger = mService.getMessenger();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (SecurityException e) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
if (messenger == null) {
|
||||
sAsyncChannel = null;
|
||||
return;
|
||||
}
|
||||
|
||||
sHandlerThread = new HandlerThread("RttManager");
|
||||
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");
|
||||
}
|
||||
}
|
||||
Messenger messenger = null;
|
||||
try {
|
||||
Log.d(TAG, "Get the messenger from " + mService);
|
||||
messenger = mService.getMessenger();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
if (messenger == null) {
|
||||
throw new IllegalStateException("getMessenger() returned null! This is invalid.");
|
||||
}
|
||||
|
||||
mAsyncChannel = new AsyncChannel();
|
||||
|
||||
Handler handler = new ServiceHandler(looper);
|
||||
mAsyncChannel.connectSync(mContext, handler, messenger);
|
||||
// We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
|
||||
// synchronously, which causes RttService to receive the wrong replyTo value.
|
||||
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
private static int putListener(Object listener) {
|
||||
private int putListener(Object listener) {
|
||||
if (listener == null) return INVALID_KEY;
|
||||
int key;
|
||||
synchronized (sListenerMapLock) {
|
||||
synchronized (mListenerMapLock) {
|
||||
do {
|
||||
key = sListenerKey++;
|
||||
key = mListenerKey++;
|
||||
} while (key == INVALID_KEY);
|
||||
sListenerMap.put(key, listener);
|
||||
mListenerMap.put(key, listener);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// Insert a listener if it doesn't exist in sListenerMap. Returns the key of the listener.
|
||||
private static int putListenerIfAbsent(Object listener) {
|
||||
// Insert a listener if it doesn't exist in mListenerMap. Returns the key of the listener.
|
||||
private int putListenerIfAbsent(Object listener) {
|
||||
if (listener == null) return INVALID_KEY;
|
||||
synchronized (sListenerMapLock) {
|
||||
synchronized (mListenerMapLock) {
|
||||
int key = getListenerKey(listener);
|
||||
if (key != INVALID_KEY) {
|
||||
return key;
|
||||
}
|
||||
do {
|
||||
key = sListenerKey++;
|
||||
key = mListenerKey++;
|
||||
} while (key == INVALID_KEY);
|
||||
sListenerMap.put(key, listener);
|
||||
mListenerMap.put(key, listener);
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Object getListener(int key) {
|
||||
private Object getListener(int key) {
|
||||
if (key == INVALID_KEY) return null;
|
||||
synchronized (sListenerMapLock) {
|
||||
Object listener = sListenerMap.get(key);
|
||||
synchronized (mListenerMapLock) {
|
||||
Object listener = mListenerMap.get(key);
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getListenerKey(Object listener) {
|
||||
private int getListenerKey(Object listener) {
|
||||
if (listener == null) return INVALID_KEY;
|
||||
synchronized (sListenerMapLock) {
|
||||
int index = sListenerMap.indexOfValue(listener);
|
||||
synchronized (mListenerMapLock) {
|
||||
int index = mListenerMap.indexOfValue(listener);
|
||||
if (index == -1) {
|
||||
return INVALID_KEY;
|
||||
} 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;
|
||||
synchronized (sListenerMapLock) {
|
||||
Object listener = sListenerMap.get(key);
|
||||
sListenerMap.remove(key);
|
||||
synchronized (mListenerMapLock) {
|
||||
Object listener = mListenerMap.get(key);
|
||||
mListenerMap.remove(key);
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
|
||||
private static int removeListener(Object listener) {
|
||||
private int removeListener(Object listener) {
|
||||
int key = getListenerKey(listener);
|
||||
if (key == INVALID_KEY) return key;
|
||||
synchronized (sListenerMapLock) {
|
||||
sListenerMap.remove(key);
|
||||
synchronized (mListenerMapLock) {
|
||||
mListenerMap.remove(key);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ServiceHandler extends Handler {
|
||||
private class ServiceHandler extends Handler {
|
||||
ServiceHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
@@ -1258,24 +1234,13 @@ public class RttManager {
|
||||
public void handleMessage(Message msg) {
|
||||
Log.i(TAG, "RTT manager get message: " + 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:
|
||||
sConnected.countDown();
|
||||
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;
|
||||
mAsyncChannel = null;
|
||||
getLooper().quit();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user