| Index: net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
|
| diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
|
| index 9f974ce9a2a8978e8db5fed2cc5d4d5829e487df..ef4410482409cc66f36e8399f9c36a8ed82695ec 100644
|
| --- a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
|
| +++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
|
| @@ -4,13 +4,18 @@
|
|
|
| package org.chromium.net.test;
|
|
|
| -import org.chromium.base.annotations.CalledByNative;
|
| -import org.chromium.base.annotations.JNINamespace;
|
| +import android.content.ComponentName;
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.content.ServiceConnection;
|
| +import android.os.IBinder;
|
| +import android.os.RemoteException;
|
| +
|
| +import org.chromium.base.Log;
|
|
|
| import java.io.File;
|
|
|
| -/**
|
| - * Java bindings for the native embedded test server.
|
| +/** A simple file server for java tests.
|
| *
|
| * An example use:
|
| * EmbeddedTestServer s = new EmbeddedTestServer();
|
| @@ -21,21 +26,76 @@ import java.io.File;
|
| * }
|
| *
|
| * // serve requests...
|
| + * s.getURL("/foo/bar.txt");
|
| *
|
| * s.shutdownAndWait();
|
| * s.destroy();
|
| + *
|
| + * Note that this runs net::test_server::EmbeddedTestServer in a service in a separate APK.
|
| */
|
| -@JNINamespace("net::test_server")
|
| public class EmbeddedTestServer {
|
| - private long mNativeEmbeddedTestServer;
|
| + private static final String TAG = "cr_TestServer";
|
| +
|
| + private static final String EMBEDDED_TEST_SERVER_SERVICE =
|
| + "org.chromium.net.test.EMBEDDED_TEST_SERVER_SERVICE";
|
| + private static final long SERVICE_CONNECTION_WAIT_INTERVAL_MS = 5000;
|
| +
|
| + private IEmbeddedTestServerImpl mImpl;
|
| + private ServiceConnection mConn = new ServiceConnection() {
|
| + @Override
|
| + public void onServiceConnected(ComponentName name, IBinder service) {
|
| + synchronized (mImplMonitor) {
|
| + mImpl = IEmbeddedTestServerImpl.Stub.asInterface(service);
|
| + mImplMonitor.notify();
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onServiceDisconnected(ComponentName name) {
|
| + synchronized (mImplMonitor) {
|
| + mImpl = null;
|
| + mImplMonitor.notify();
|
| + }
|
| + }
|
| + };
|
| +
|
| + private final Object mImplMonitor = new Object();
|
|
|
| - /** Create an uninitialized EmbeddedTestServer. */
|
| - public EmbeddedTestServer() {}
|
| + /**
|
| + * Exception class raised on failure in the EmbeddedTestServer.
|
| + */
|
| + public static final class EmbeddedTestServerFailure extends Error {
|
| + public EmbeddedTestServerFailure(String errorDesc) {
|
| + super(errorDesc);
|
| + }
|
| +
|
| + public EmbeddedTestServerFailure(String errorDesc, Throwable cause) {
|
| + super(errorDesc, cause);
|
| + }
|
| + }
|
|
|
| - /** Initialize the native EmbeddedTestServer object. */
|
| - public void initializeNative() {
|
| - if (mNativeEmbeddedTestServer == 0) nativeInit();
|
| - assert mNativeEmbeddedTestServer != 0;
|
| + public void initializeNative(Context context) throws InterruptedException {
|
| + Intent intent = new Intent(EMBEDDED_TEST_SERVER_SERVICE);
|
| + intent.setClassName(
|
| + "org.chromium.net.test.support", "org.chromium.net.test.EmbeddedTestServerService");
|
| + if (!context.bindService(intent, mConn, Context.BIND_AUTO_CREATE)) {
|
| + throw new EmbeddedTestServerFailure(
|
| + "Unable to bind to the EmbeddedTestServer service.");
|
| + }
|
| + synchronized (mImplMonitor) {
|
| + Log.i(TAG, "Waiting for EmbeddedTestServer service connection.");
|
| + while (mImpl == null) {
|
| + mImplMonitor.wait(SERVICE_CONNECTION_WAIT_INTERVAL_MS);
|
| + Log.i(TAG, "Still waiting for EmbeddedTestServer service connection.");
|
| + }
|
| + Log.i(TAG, "EmbeddedTestServer service connected.");
|
| + try {
|
| + mImpl.initializeNative();
|
| + } catch (RemoteException e) {
|
| + Log.e(TAG, "Failed to initialize native server.", e);
|
| + throw new EmbeddedTestServerFailure("Failed to initialize native server.");
|
| + }
|
| + }
|
| }
|
|
|
| /** Serve files from the provided directory.
|
| @@ -43,7 +103,7 @@ public class EmbeddedTestServer {
|
| * @param directory The directory from which files should be served.
|
| */
|
| public void serveFilesFromDirectory(File directory) {
|
| - nativeServeFilesFromDirectory(mNativeEmbeddedTestServer, directory.getPath());
|
| + serveFilesFromDirectory(directory.getPath());
|
| }
|
|
|
| /** Serve files from the provided directory.
|
| @@ -51,7 +111,21 @@ public class EmbeddedTestServer {
|
| * @param directoryPath The path of the directory from which files should be served.
|
| */
|
| public void serveFilesFromDirectory(String directoryPath) {
|
| - nativeServeFilesFromDirectory(mNativeEmbeddedTestServer, directoryPath);
|
| + try {
|
| + synchronized (mImplMonitor) {
|
| + checkServiceLocked();
|
| + mImpl.serveFilesFromDirectory(directoryPath);
|
| + }
|
| + } catch (RemoteException e) {
|
| + throw new EmbeddedTestServerFailure(
|
| + "Failed to start serving files from " + directoryPath + ": " + e.toString());
|
| + }
|
| + }
|
| +
|
| + private void checkServiceLocked() {
|
| + if (mImpl == null) {
|
| + throw new EmbeddedTestServerFailure("Service disconnected.");
|
| + }
|
| }
|
|
|
| /** Starts the server.
|
| @@ -62,7 +136,35 @@ public class EmbeddedTestServer {
|
| * @return Whether the server was successfully initialized.
|
| */
|
| public boolean start() {
|
| - return nativeStart(mNativeEmbeddedTestServer);
|
| + try {
|
| + synchronized (mImplMonitor) {
|
| + checkServiceLocked();
|
| + return mImpl.start();
|
| + }
|
| + } catch (RemoteException e) {
|
| + throw new EmbeddedTestServerFailure("Failed to start server.", e);
|
| + }
|
| + }
|
| +
|
| + /** Create and initialize a server that serves files from the provided directory.
|
| + *
|
| + * This handles native object initialization, server configuration, and server initialization.
|
| + * On returning, the server is ready for use.
|
| + *
|
| + * @param context The context in which the server is being started.
|
| + * @param directory The directory from which files should be served.
|
| + * @return The created server.
|
| + */
|
| + public static EmbeddedTestServer createAndStartFileServer(Context context, File directory)
|
| + throws InterruptedException {
|
| + EmbeddedTestServer server = new EmbeddedTestServer();
|
| + server.initializeNative(context);
|
| + server.serveFilesFromDirectory(directory);
|
| + if (!server.start()) {
|
| + throw new EmbeddedTestServerFailure(
|
| + "Failed to start serving files from " + directory.getPath());
|
| + }
|
| + return server;
|
| }
|
|
|
| /** Get the full URL for the given relative URL.
|
| @@ -71,7 +173,14 @@ public class EmbeddedTestServer {
|
| * @return The URL as a String.
|
| */
|
| public String getURL(String relativeUrl) {
|
| - return nativeGetURL(mNativeEmbeddedTestServer, relativeUrl);
|
| + try {
|
| + synchronized (mImplMonitor) {
|
| + checkServiceLocked();
|
| + return mImpl.getURL(relativeUrl);
|
| + }
|
| + } catch (RemoteException e) {
|
| + throw new EmbeddedTestServerFailure("Failed to get URL for " + relativeUrl, e);
|
| + }
|
| }
|
|
|
| /** Shutdown the server.
|
| @@ -79,33 +188,40 @@ public class EmbeddedTestServer {
|
| * @return Whether the server was successfully shut down.
|
| */
|
| public boolean shutdownAndWaitUntilComplete() {
|
| - return nativeShutdownAndWaitUntilComplete(mNativeEmbeddedTestServer);
|
| + try {
|
| + synchronized (mImplMonitor) {
|
| + checkServiceLocked();
|
| + return mImpl.shutdownAndWaitUntilComplete();
|
| + }
|
| + } catch (RemoteException e) {
|
| + throw new EmbeddedTestServerFailure("Failed to shut down.", e);
|
| + }
|
| }
|
|
|
| /** Destroy the native EmbeddedTestServer object. */
|
| - public void destroy() {
|
| - assert mNativeEmbeddedTestServer != 0;
|
| - nativeDestroy(mNativeEmbeddedTestServer);
|
| - assert mNativeEmbeddedTestServer == 0;
|
| + public void destroy(Context context) {
|
| + try {
|
| + synchronized (mImplMonitor) {
|
| + checkServiceLocked();
|
| + mImpl.destroy();
|
| + }
|
| + } catch (RemoteException e) {
|
| + throw new EmbeddedTestServerFailure("Failed to destroy native server.", e);
|
| + } finally {
|
| + context.unbindService(mConn);
|
| + }
|
| }
|
|
|
| - @CalledByNative
|
| - private void setNativePtr(long nativePtr) {
|
| - assert mNativeEmbeddedTestServer == 0;
|
| - mNativeEmbeddedTestServer = nativePtr;
|
| - }
|
| -
|
| - @CalledByNative
|
| - private void clearNativePtr() {
|
| - assert mNativeEmbeddedTestServer != 0;
|
| - mNativeEmbeddedTestServer = 0;
|
| + /** Stop and destroy the provided server.
|
| + *
|
| + * This handles stopping the server and destroying the native object.
|
| + *
|
| + * @param server The server to stop and destroy.
|
| + */
|
| + public static void stopAndDestroyServer(EmbeddedTestServer server, Context context) {
|
| + if (!server.shutdownAndWaitUntilComplete()) {
|
| + throw new EmbeddedTestServerFailure("Failed to stop server.");
|
| + }
|
| + server.destroy(context);
|
| }
|
| -
|
| - private native void nativeInit();
|
| - private native void nativeDestroy(long nativeEmbeddedTestServerAndroid);
|
| - private native boolean nativeStart(long nativeEmbeddedTestServerAndroid);
|
| - private native boolean nativeShutdownAndWaitUntilComplete(long nativeEmbeddedTestServerAndroid);
|
| - private native String nativeGetURL(long nativeEmbeddedTestServerAndroid, String relativeUrl);
|
| - private native void nativeServeFilesFromDirectory(
|
| - long nativeEmbeddedTestServerAndroid, String directoryPath);
|
| }
|
|
|