Add a simple test for NetworkManagementService.
For now, this only tests network observers. It works by starting
NetworkManagementService with a fake netd socket, feeding it
inputs, and seeing if the appropriate observer methods are
called.
Bug: 10232006
Change-Id: I827681575642a4ee13ae48b81272521544b676bd
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index a9942e3..417d6d8 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -18,6 +18,7 @@
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
+import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
@@ -105,13 +106,24 @@
return true;
}
+ private LocalSocketAddress determineSocketAddress() {
+ // If we're testing, set up a socket in a namespace that's accessible to test code.
+ // In order to ensure that unprivileged apps aren't able to impersonate native daemons on
+ // production devices, even if said native daemons ill-advisedly pick a socket name that
+ // starts with __test__, only allow this on debug builds.
+ if (mSocket.startsWith("__test__") && Build.IS_DEBUGGABLE) {
+ return new LocalSocketAddress(mSocket);
+ } else {
+ return new LocalSocketAddress(mSocket, LocalSocketAddress.Namespace.RESERVED);
+ }
+ }
+
private void listenToSocket() throws IOException {
LocalSocket socket = null;
try {
socket = new LocalSocket();
- LocalSocketAddress address = new LocalSocketAddress(mSocket,
- LocalSocketAddress.Namespace.RESERVED);
+ LocalSocketAddress address = determineSocketAddress();
socket.connect(address);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 16cfa666..dfcab29 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -95,6 +95,7 @@
private static final String TAG = "NetworkManagementService";
private static final boolean DBG = false;
private static final String NETD_TAG = "NetdConnector";
+ private static final String NETD_SOCKET_NAME = "netd";
private static final String ADD = "add";
private static final String REMOVE = "remove";
@@ -187,7 +188,7 @@
*
* @param context Binder context for this service
*/
- private NetworkManagementService(Context context) {
+ private NetworkManagementService(Context context, String socket) {
mContext = context;
if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
@@ -195,15 +196,16 @@
}
mConnector = new NativeDaemonConnector(
- new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160);
+ new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160);
mThread = new Thread(mConnector, NETD_TAG);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
}
- public static NetworkManagementService create(Context context) throws InterruptedException {
- final NetworkManagementService service = new NetworkManagementService(context);
+ static NetworkManagementService create(Context context,
+ String socket) throws InterruptedException {
+ final NetworkManagementService service = new NetworkManagementService(context, socket);
final CountDownLatch connectedSignal = service.mConnectedSignal;
if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
service.mThread.start();
@@ -213,6 +215,10 @@
return service;
}
+ public static NetworkManagementService create(Context context) throws InterruptedException {
+ return create(context, NETD_SOCKET_NAME);
+ }
+
public void systemReady() {
prepareNativeDaemon();
if (DBG) Slog.d(TAG, "Prepared");