Chromium Code Reviews| Index: net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java |
| diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3d17b0930a8d8d3eb93893d6bcb9e381c53c78b5 |
| --- /dev/null |
| +++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java |
| @@ -0,0 +1,182 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.net.test; |
| + |
| +import android.os.Handler; |
| +import android.os.HandlerThread; |
| + |
| +import org.chromium.base.Log; |
| +import org.chromium.base.annotations.CalledByNative; |
| +import org.chromium.base.annotations.JNINamespace; |
| +import org.chromium.base.test.library_loader.TestLibraryLoader; |
| + |
| +import java.util.concurrent.Callable; |
| +import java.util.concurrent.ExecutionException; |
| +import java.util.concurrent.FutureTask; |
| +import java.util.concurrent.atomic.AtomicInteger; |
| + |
| +/** |
| + * Java bindings for the native embedded test server. |
|
mef
2015/11/25 17:20:22
This comment is wrong.
jbudorick
2015/12/01 15:38:23
Here the first sentence is right, but everything e
|
| + * |
| + * An example use: |
| + * EmbeddedTestServer s = new EmbeddedTestServer(); |
| + * s.initializeNative(); |
| + * s.serveFilesFromDirectory("/path/to/my/directory"); |
| + * if (!s.start()) { |
| + * throw new SomeKindOfException("Unable to initialize EmbeddedTestServer."); |
| + * } |
| + * |
| + * // serve requests... |
| + * |
| + * s.shutdownAndWait(); |
| + * s.destroy(); |
| + */ |
| +@JNINamespace("net::test_server") |
| +public class EmbeddedTestServerImpl extends IEmbeddedTestServerImpl.Stub { |
| + private static final String TAG = "cr_TestServer"; |
| + |
| + private static AtomicInteger sCount = new AtomicInteger(); |
| + |
| + private Handler mHandler; |
| + private HandlerThread mHandlerThread; |
| + private long mNativeEmbeddedTestServer; |
| + |
| + /** Create an uninitialized EmbeddedTestServer. */ |
| + public EmbeddedTestServerImpl() {} |
| + |
| + private <V> V runOnHandlerThread(Callable<V> c) { |
| + FutureTask<V> t = new FutureTask<V>(c); |
| + mHandler.post(t); |
| + try { |
| + return t.get(); |
| + } catch (ExecutionException e) { |
| + Log.e(TAG, "Exception raised from native EmbeddedTestServer", e); |
| + } catch (InterruptedException e) { |
| + Log.e(TAG, "Interrupted while waiting for native EmbeddedTestServer", e); |
| + return null; |
| + } |
| + return null; |
| + } |
| + |
| + /** Initialize the native EmbeddedTestServer object. */ |
| + public void initializeNative() { |
| + mHandlerThread = new HandlerThread("EmbeddedTestServer" + sCount.getAndIncrement()); |
| + mHandlerThread.start(); |
| + mHandler = new Handler(mHandlerThread.getLooper()); |
| + |
| + runOnHandlerThread(new Callable<Void>() { |
| + @Override |
| + public Void call() { |
| + Log.i(TAG, "initializeNative thread ID: %d", Thread.currentThread().getId()); |
| + TestLibraryLoader.loadLibraries(); |
|
mef
2015/11/25 17:20:22
Is this Ok to run multiple times? Does it need to
jbudorick
2015/12/01 15:38:23
AFAICT it should be fine, but no, it doesn't need
|
| + if (mNativeEmbeddedTestServer == 0) nativeInit(); |
|
mef
2015/11/25 17:20:22
In what circumstances is mNativeEmbeddedTestServer
jbudorick
2015/12/01 15:38:23
In normal use, it shouldn't be. If a client called
|
| + assert mNativeEmbeddedTestServer != 0; |
| + return null; |
| + } |
| + }); |
| + } |
| + |
| + /** Serve files from the provided directory. |
| + * |
| + * @param directoryPath The path of the directory from which files should be served. |
| + */ |
| + public void serveFilesFromDirectory(final String directoryPath) { |
| + runOnHandlerThread(new Callable<Void>() { |
| + @Override |
| + public Void call() { |
| + Log.i(TAG, "serveFilesFromDirectory thread ID: %d", Thread.currentThread().getId()); |
| + nativeServeFilesFromDirectory(mNativeEmbeddedTestServer, directoryPath); |
|
mef
2015/11/25 17:20:22
I think this should check for directory existence
jbudorick
2015/12/01 15:38:23
I had intended to deviate as little as possible fr
|
| + return null; |
| + } |
| + }); |
| + } |
| + |
| + /** Starts the server. |
| + * |
| + * Note that this should be called after handlers are set up, including any relevant calls |
| + * serveFilesFromDirectory. |
| + * |
| + * @return Whether the server was successfully started. |
| + */ |
| + public boolean start() { |
| + return runOnHandlerThread(new Callable<Boolean>() { |
| + @Override |
| + public Boolean call() { |
| + Log.i(TAG, "start thread ID: %d", Thread.currentThread().getId()); |
| + return nativeStart(mNativeEmbeddedTestServer); |
| + } |
| + }); |
| + } |
| + |
| + /** Get the full URL for the given relative URL. |
| + * |
| + * @param relativeUrl The relative URL for which a full URL should be returned. |
| + * @return The URL as a String. |
| + */ |
| + public String getURL(final String relativeUrl) { |
| + return runOnHandlerThread(new Callable<String>() { |
| + @Override |
| + public String call() { |
| + Log.i(TAG, "getURL thread ID: %d", Thread.currentThread().getId()); |
| + return nativeGetURL(mNativeEmbeddedTestServer, relativeUrl); |
| + } |
| + }); |
| + } |
| + |
| + /** Shut down the server. |
| + * |
| + * @return Whether the server was successfully shut down. |
| + */ |
| + public boolean shutdownAndWaitUntilComplete() { |
| + return runOnHandlerThread(new Callable<Boolean>() { |
| + @Override |
| + public Boolean call() { |
| + Log.i(TAG, "shutdownAndWaitUntilComplete thread ID: %d", |
| + Thread.currentThread().getId()); |
| + return nativeShutdownAndWaitUntilComplete(mNativeEmbeddedTestServer); |
| + } |
| + }); |
| + } |
| + |
| + /** Destroy the native EmbeddedTestServer object. */ |
| + public void destroy() { |
| + runOnHandlerThread(new Callable<Void>() { |
| + @Override |
| + public Void call() { |
| + Log.i(TAG, "destroy thread ID: %d", Thread.currentThread().getId()); |
| + assert mNativeEmbeddedTestServer != 0; |
| + nativeDestroy(mNativeEmbeddedTestServer); |
| + assert mNativeEmbeddedTestServer == 0; |
| + return null; |
| + } |
| + }); |
| + |
| + mHandlerThread.quitSafely(); |
| + try { |
| + mHandlerThread.join(); |
|
Yaron
2015/11/25 16:04:55
I'm wondering what's better in the case of failure
jbudorick
2015/12/01 15:38:23
That actually raises a good point; EmbeddedTestSer
|
| + } catch (InterruptedException e) { |
| + } |
| + } |
| + |
| + @CalledByNative |
| + private void setNativePtr(long nativePtr) { |
| + assert mNativeEmbeddedTestServer == 0; |
| + mNativeEmbeddedTestServer = nativePtr; |
| + } |
| + |
| + @CalledByNative |
| + private void clearNativePtr() { |
| + assert mNativeEmbeddedTestServer != 0; |
| + mNativeEmbeddedTestServer = 0; |
| + } |
| + |
| + 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); |
| +} |