summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/RttService.java108
1 files changed, 85 insertions, 23 deletions
diff --git a/service/java/com/android/server/wifi/RttService.java b/service/java/com/android/server/wifi/RttService.java
index 3eafc77f6..7b3d9f955 100644
--- a/service/java/com/android/server/wifi/RttService.java
+++ b/service/java/com/android/server/wifi/RttService.java
@@ -5,10 +5,12 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.net.wifi.IRttManager;
import android.net.wifi.RttManager;
import android.net.wifi.RttManager.ResponderConfig;
import android.net.wifi.WifiManager;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -16,16 +18,20 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.IState;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.SystemService;
-import java.util.HashMap;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -65,20 +71,27 @@ public final class RttService extends SystemService {
if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
}
if (DBG) Slog.d(TAG, "closing client " + msg.replyTo);
- ClientInfo ci = mClients.remove(msg.replyTo);
- if (ci != null) ci.cleanup();
+ synchronized (mLock) {
+ ClientInfo ci = mClients.remove(msg.replyTo);
+ if (ci != null) ci.cleanup();
+ }
return;
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
AsyncChannel ac = new AsyncChannel();
ac.connected(mContext, this, msg.replyTo);
- ClientInfo client = new ClientInfo(ac, msg.replyTo);
- mClients.put(msg.replyTo, client);
+ ClientInfo client = new ClientInfo(ac, msg.sendingUid);
+ synchronized (mLock) {
+ mClients.put(msg.replyTo, client);
+ }
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
AsyncChannel.STATUS_SUCCESSFUL);
return;
}
- ClientInfo ci = mClients.get(msg.replyTo);
+ ClientInfo ci;
+ synchronized (mLock) {
+ ci = mClients.get(msg.replyTo);
+ }
if (ci == null) {
Slog.e(TAG, "Could not find client info for message " + msg.replyTo);
replyFailed(msg, RttManager.REASON_INVALID_LISTENER, "Could not find listener");
@@ -170,15 +183,15 @@ public final class RttService extends SystemService {
private class ClientInfo {
private final AsyncChannel mChannel;
- private final Messenger mMessenger;
- HashMap<Integer, RttRequest> mRequests = new HashMap<Integer,
- RttRequest>();
+ private final int mUid;
+
+ ArrayMap<Integer, RttRequest> mRequests = new ArrayMap<>();
// Client keys of all outstanding responders.
Set<Integer> mResponderRequests = new HashSet<>();
- ClientInfo(AsyncChannel c, Messenger m) {
- mChannel = c;
- mMessenger = m;
+ ClientInfo(AsyncChannel channel, int uid) {
+ mChannel = channel;
+ mUid = uid;
}
void addResponderRequest(int key) {
@@ -215,7 +228,7 @@ public final class RttService extends SystemService {
void reportResponderEnableFailed(int key, int reason) {
mChannel.sendMessage(RttManager.CMD_OP_ENALBE_RESPONDER_FAILED, reason, key);
- mResponderRequests.remove(key);
+ removeResponderRequest(key);
}
void reportResult(RttRequest request, RttManager.RttResult[] results) {
@@ -224,7 +237,7 @@ public final class RttService extends SystemService {
mChannel.sendMessage(RttManager.CMD_OP_SUCCEEDED,
0, request.key, parcelableResults);
- mRequests.remove(request.key);
+ removeRttRequest(request.key);
}
void reportFailed(RttRequest request, int reason, String description) {
@@ -235,7 +248,7 @@ public final class RttService extends SystemService {
Bundle bundle = new Bundle();
bundle.putString(RttManager.DESCRIPTION_KEY, description);
mChannel.sendMessage(RttManager.CMD_OP_FAILED, key, reason, bundle);
- mRequests.remove(key);
+ removeRttRequest(key);
}
void reportAborted(int key) {
@@ -252,10 +265,19 @@ public final class RttService extends SystemService {
mResponderRequests.clear();
mStateMachine.sendMessage(RttManager.CMD_OP_DISABLE_RESPONDER);
}
+
+ @Override
+ public String toString() {
+ return "ClientInfo [uid=" + mUid + ", channel=" + mChannel + "]";
+ }
}
- private Queue<RttRequest> mRequestQueue = new LinkedList<RttRequest>();
- private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(4);
+ private Queue<RttRequest> mRequestQueue = new LinkedList<>();
+
+ @GuardedBy("mLock")
+ private ArrayMap<Messenger, ClientInfo> mClients = new ArrayMap<>();
+ // Lock for mClients.
+ private final Object mLock = new Object();
private static final int BASE = Protocol.BASE_WIFI_RTT_SERVICE;
@@ -305,7 +327,11 @@ public final class RttService extends SystemService {
case RttManager.CMD_OP_STOP_RANGING:
return HANDLED;
case RttManager.CMD_OP_ENABLE_RESPONDER:
- ClientInfo client = mClients.get(msg.replyTo);
+
+ ClientInfo client;
+ synchronized (mLock) {
+ client = mClients.get(msg.replyTo);
+ }
if (client == null) {
Log.e(TAG, "client not connected yet!");
break;
@@ -327,7 +353,10 @@ public final class RttService extends SystemService {
@Override
public boolean processMessage(Message msg) {
if (DBG) Log.d(TAG, "EnabledState got" + msg);
- ClientInfo ci = mClients.get(msg.replyTo);
+ ClientInfo ci;
+ synchronized (mLock) {
+ ci = mClients.get(msg.replyTo);
+ }
switch (msg.what) {
case CMD_DRIVER_UNLOADED:
@@ -455,9 +484,11 @@ public final class RttService extends SystemService {
// Check if there are still outstanding responder requests from any client.
private boolean hasOutstandingReponderRequests() {
- for (ClientInfo client : mClients.values()) {
- if (!client.mResponderRequests.isEmpty()) {
- return true;
+ synchronized (mLock) {
+ for (ClientInfo client : mClients.values()) {
+ if (!client.mResponderRequests.isEmpty()) {
+ return true;
+ }
}
}
return false;
@@ -470,7 +501,10 @@ public final class RttService extends SystemService {
@Override
public boolean processMessage(Message msg) {
if (DBG) Log.d(TAG, "ResponderEnabledState got " + msg);
- ClientInfo ci = mClients.get(msg.replyTo);
+ ClientInfo ci;
+ synchronized (mLock) {
+ ci = mClients.get(msg.replyTo);
+ }
int key = msg.arg2;
switch(msg.what) {
case RttManager.CMD_OP_ENABLE_RESPONDER:
@@ -503,6 +537,14 @@ public final class RttService extends SystemService {
}
}
}
+
+ /**
+ * Returns name of current state.
+ */
+ String currentState() {
+ IState state = getCurrentState();
+ return state == null ? "null" : state.getName();
+ }
}
void replySucceeded(Message msg, Object obj) {
@@ -551,6 +593,26 @@ public final class RttService extends SystemService {
return true;
}
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump RttService from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " without permission "
+ + android.Manifest.permission.DUMP);
+ return;
+ }
+ pw.println("current state: " + mStateMachine.currentState());
+ pw.println("clients:");
+ synchronized (mLock) {
+ for (ClientInfo client : mClients.values()) {
+ pw.println(" " + client);
+ }
+ }
+ }
+
private WifiNative.RttEventHandler mEventHandler = new WifiNative.RttEventHandler() {
@Override
public void onRttResults(RttManager.RttResult[] result) {