OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.net.test; | 5 package org.chromium.net.test; |
6 | 6 |
7 import org.chromium.base.annotations.CalledByNative; | 7 import android.content.ComponentName; |
8 import org.chromium.base.annotations.JNINamespace; | 8 import android.content.Context; |
| 9 import android.content.Intent; |
| 10 import android.content.ServiceConnection; |
| 11 import android.os.IBinder; |
| 12 import android.os.RemoteException; |
| 13 |
| 14 import org.chromium.base.Log; |
9 | 15 |
10 import java.io.File; | 16 import java.io.File; |
11 | 17 |
12 /** | 18 /** A simple file server for java tests. |
13 * Java bindings for the native embedded test server. | |
14 * | 19 * |
15 * An example use: | 20 * An example use: |
16 * EmbeddedTestServer s = new EmbeddedTestServer(); | 21 * EmbeddedTestServer s = new EmbeddedTestServer(); |
17 * s.initializeNative(); | 22 * s.initializeNative(); |
18 * s.serveFilesFromDirectory("/path/to/my/directory"); | 23 * s.serveFilesFromDirectory("/path/to/my/directory"); |
19 * if (!s.start()) { | 24 * if (!s.start()) { |
20 * throw new SomeKindOfException("Unable to initialize EmbeddedTestServer.
"); | 25 * throw new SomeKindOfException("Unable to initialize EmbeddedTestServer.
"); |
21 * } | 26 * } |
22 * | 27 * |
23 * // serve requests... | 28 * // serve requests... |
| 29 * s.getURL("/foo/bar.txt"); |
24 * | 30 * |
25 * s.shutdownAndWait(); | 31 * s.shutdownAndWait(); |
26 * s.destroy(); | 32 * s.destroy(); |
| 33 * |
| 34 * Note that this runs net::test_server::EmbeddedTestServer in a service in a se
parate APK. |
27 */ | 35 */ |
28 @JNINamespace("net::test_server") | |
29 public class EmbeddedTestServer { | 36 public class EmbeddedTestServer { |
30 private long mNativeEmbeddedTestServer; | 37 private static final String TAG = "cr_TestServer"; |
31 | 38 |
32 /** Create an uninitialized EmbeddedTestServer. */ | 39 private static final String EMBEDDED_TEST_SERVER_SERVICE = |
33 public EmbeddedTestServer() {} | 40 "org.chromium.net.test.EMBEDDED_TEST_SERVER_SERVICE"; |
| 41 private static final long SERVICE_CONNECTION_WAIT_INTERVAL_MS = 5000; |
34 | 42 |
35 /** Initialize the native EmbeddedTestServer object. */ | 43 private IEmbeddedTestServerImpl mImpl; |
36 public void initializeNative() { | 44 private ServiceConnection mConn = new ServiceConnection() { |
37 if (mNativeEmbeddedTestServer == 0) nativeInit(); | 45 @Override |
38 assert mNativeEmbeddedTestServer != 0; | 46 public void onServiceConnected(ComponentName name, IBinder service) { |
| 47 synchronized (mImplMonitor) { |
| 48 mImpl = IEmbeddedTestServerImpl.Stub.asInterface(service); |
| 49 mImplMonitor.notify(); |
| 50 } |
| 51 } |
| 52 |
| 53 @Override |
| 54 public void onServiceDisconnected(ComponentName name) { |
| 55 synchronized (mImplMonitor) { |
| 56 mImpl = null; |
| 57 mImplMonitor.notify(); |
| 58 } |
| 59 } |
| 60 }; |
| 61 |
| 62 private final Object mImplMonitor = new Object(); |
| 63 |
| 64 /** |
| 65 * Exception class raised on failure in the EmbeddedTestServer. |
| 66 */ |
| 67 public static final class EmbeddedTestServerFailure extends Error { |
| 68 public EmbeddedTestServerFailure(String errorDesc) { |
| 69 super(errorDesc); |
| 70 } |
| 71 |
| 72 public EmbeddedTestServerFailure(String errorDesc, Throwable cause) { |
| 73 super(errorDesc, cause); |
| 74 } |
| 75 } |
| 76 |
| 77 public void initializeNative(Context context) throws InterruptedException { |
| 78 Intent intent = new Intent(EMBEDDED_TEST_SERVER_SERVICE); |
| 79 intent.setClassName( |
| 80 "org.chromium.net.test.support", "org.chromium.net.test.Embedded
TestServerService"); |
| 81 if (!context.bindService(intent, mConn, Context.BIND_AUTO_CREATE)) { |
| 82 throw new EmbeddedTestServerFailure( |
| 83 "Unable to bind to the EmbeddedTestServer service."); |
| 84 } |
| 85 synchronized (mImplMonitor) { |
| 86 Log.i(TAG, "Waiting for EmbeddedTestServer service connection."); |
| 87 while (mImpl == null) { |
| 88 mImplMonitor.wait(SERVICE_CONNECTION_WAIT_INTERVAL_MS); |
| 89 Log.i(TAG, "Still waiting for EmbeddedTestServer service connect
ion."); |
| 90 } |
| 91 Log.i(TAG, "EmbeddedTestServer service connected."); |
| 92 try { |
| 93 mImpl.initializeNative(); |
| 94 } catch (RemoteException e) { |
| 95 Log.e(TAG, "Failed to initialize native server.", e); |
| 96 throw new EmbeddedTestServerFailure("Failed to initialize native
server."); |
| 97 } |
| 98 } |
39 } | 99 } |
40 | 100 |
41 /** Serve files from the provided directory. | 101 /** Serve files from the provided directory. |
42 * | 102 * |
43 * @param directory The directory from which files should be served. | 103 * @param directory The directory from which files should be served. |
44 */ | 104 */ |
45 public void serveFilesFromDirectory(File directory) { | 105 public void serveFilesFromDirectory(File directory) { |
46 nativeServeFilesFromDirectory(mNativeEmbeddedTestServer, directory.getPa
th()); | 106 serveFilesFromDirectory(directory.getPath()); |
47 } | 107 } |
48 | 108 |
49 /** Serve files from the provided directory. | 109 /** Serve files from the provided directory. |
50 * | 110 * |
51 * @param directoryPath The path of the directory from which files should b
e served. | 111 * @param directoryPath The path of the directory from which files should b
e served. |
52 */ | 112 */ |
53 public void serveFilesFromDirectory(String directoryPath) { | 113 public void serveFilesFromDirectory(String directoryPath) { |
54 nativeServeFilesFromDirectory(mNativeEmbeddedTestServer, directoryPath); | 114 try { |
| 115 synchronized (mImplMonitor) { |
| 116 checkServiceLocked(); |
| 117 mImpl.serveFilesFromDirectory(directoryPath); |
| 118 } |
| 119 } catch (RemoteException e) { |
| 120 throw new EmbeddedTestServerFailure( |
| 121 "Failed to start serving files from " + directoryPath + ": "
+ e.toString()); |
| 122 } |
| 123 } |
| 124 |
| 125 private void checkServiceLocked() { |
| 126 if (mImpl == null) { |
| 127 throw new EmbeddedTestServerFailure("Service disconnected."); |
| 128 } |
55 } | 129 } |
56 | 130 |
57 /** Starts the server. | 131 /** Starts the server. |
58 * | 132 * |
59 * Note that this should be called after handlers are set up, including any
relevant calls | 133 * Note that this should be called after handlers are set up, including any
relevant calls |
60 * serveFilesFromDirectory. | 134 * serveFilesFromDirectory. |
61 * | 135 * |
62 * @return Whether the server was successfully initialized. | 136 * @return Whether the server was successfully initialized. |
63 */ | 137 */ |
64 public boolean start() { | 138 public boolean start() { |
65 return nativeStart(mNativeEmbeddedTestServer); | 139 try { |
| 140 synchronized (mImplMonitor) { |
| 141 checkServiceLocked(); |
| 142 return mImpl.start(); |
| 143 } |
| 144 } catch (RemoteException e) { |
| 145 throw new EmbeddedTestServerFailure("Failed to start server.", e); |
| 146 } |
| 147 } |
| 148 |
| 149 /** Create and initialize a server that serves files from the provided direc
tory. |
| 150 * |
| 151 * This handles native object initialization, server configuration, and ser
ver initialization. |
| 152 * On returning, the server is ready for use. |
| 153 * |
| 154 * @param context The context in which the server is being started. |
| 155 * @param directory The directory from which files should be served. |
| 156 * @return The created server. |
| 157 */ |
| 158 public static EmbeddedTestServer createAndStartFileServer(Context context, F
ile directory) |
| 159 throws InterruptedException { |
| 160 EmbeddedTestServer server = new EmbeddedTestServer(); |
| 161 server.initializeNative(context); |
| 162 server.serveFilesFromDirectory(directory); |
| 163 if (!server.start()) { |
| 164 throw new EmbeddedTestServerFailure( |
| 165 "Failed to start serving files from " + directory.getPath())
; |
| 166 } |
| 167 return server; |
66 } | 168 } |
67 | 169 |
68 /** Get the full URL for the given relative URL. | 170 /** Get the full URL for the given relative URL. |
69 * | 171 * |
70 * @param relativeUrl The relative URL for which a full URL will be obtaine
d. | 172 * @param relativeUrl The relative URL for which a full URL will be obtaine
d. |
71 * @return The URL as a String. | 173 * @return The URL as a String. |
72 */ | 174 */ |
73 public String getURL(String relativeUrl) { | 175 public String getURL(String relativeUrl) { |
74 return nativeGetURL(mNativeEmbeddedTestServer, relativeUrl); | 176 try { |
| 177 synchronized (mImplMonitor) { |
| 178 checkServiceLocked(); |
| 179 return mImpl.getURL(relativeUrl); |
| 180 } |
| 181 } catch (RemoteException e) { |
| 182 throw new EmbeddedTestServerFailure("Failed to get URL for " + relat
iveUrl, e); |
| 183 } |
75 } | 184 } |
76 | 185 |
77 /** Shutdown the server. | 186 /** Shutdown the server. |
78 * | 187 * |
79 * @return Whether the server was successfully shut down. | 188 * @return Whether the server was successfully shut down. |
80 */ | 189 */ |
81 public boolean shutdownAndWaitUntilComplete() { | 190 public boolean shutdownAndWaitUntilComplete() { |
82 return nativeShutdownAndWaitUntilComplete(mNativeEmbeddedTestServer); | 191 try { |
| 192 synchronized (mImplMonitor) { |
| 193 checkServiceLocked(); |
| 194 return mImpl.shutdownAndWaitUntilComplete(); |
| 195 } |
| 196 } catch (RemoteException e) { |
| 197 throw new EmbeddedTestServerFailure("Failed to shut down.", e); |
| 198 } |
83 } | 199 } |
84 | 200 |
85 /** Destroy the native EmbeddedTestServer object. */ | 201 /** Destroy the native EmbeddedTestServer object. */ |
86 public void destroy() { | 202 public void destroy(Context context) { |
87 assert mNativeEmbeddedTestServer != 0; | 203 try { |
88 nativeDestroy(mNativeEmbeddedTestServer); | 204 synchronized (mImplMonitor) { |
89 assert mNativeEmbeddedTestServer == 0; | 205 checkServiceLocked(); |
| 206 mImpl.destroy(); |
| 207 } |
| 208 } catch (RemoteException e) { |
| 209 throw new EmbeddedTestServerFailure("Failed to destroy native server
.", e); |
| 210 } finally { |
| 211 context.unbindService(mConn); |
| 212 } |
90 } | 213 } |
91 | 214 |
92 @CalledByNative | 215 /** Stop and destroy the provided server. |
93 private void setNativePtr(long nativePtr) { | 216 * |
94 assert mNativeEmbeddedTestServer == 0; | 217 * This handles stopping the server and destroying the native object. |
95 mNativeEmbeddedTestServer = nativePtr; | 218 * |
| 219 * @param server The server to stop and destroy. |
| 220 */ |
| 221 public static void stopAndDestroyServer(EmbeddedTestServer server, Context c
ontext) { |
| 222 if (!server.shutdownAndWaitUntilComplete()) { |
| 223 throw new EmbeddedTestServerFailure("Failed to stop server."); |
| 224 } |
| 225 server.destroy(context); |
96 } | 226 } |
97 | |
98 @CalledByNative | |
99 private void clearNativePtr() { | |
100 assert mNativeEmbeddedTestServer != 0; | |
101 mNativeEmbeddedTestServer = 0; | |
102 } | |
103 | |
104 private native void nativeInit(); | |
105 private native void nativeDestroy(long nativeEmbeddedTestServerAndroid); | |
106 private native boolean nativeStart(long nativeEmbeddedTestServerAndroid); | |
107 private native boolean nativeShutdownAndWaitUntilComplete(long nativeEmbedde
dTestServerAndroid); | |
108 private native String nativeGetURL(long nativeEmbeddedTestServerAndroid, Str
ing relativeUrl); | |
109 private native void nativeServeFilesFromDirectory( | |
110 long nativeEmbeddedTestServerAndroid, String directoryPath); | |
111 } | 227 } |
OLD | NEW |