Merge "Use ConnectivityThread for RttManager." into nyc-dev

This commit is contained in:
Wei Wang
2016-04-18 21:17:24 +00:00
committed by Android (Google) Code Review
2 changed files with 62 additions and 96 deletions

View File

@@ -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,

View File

@@ -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;
} }