blob: 6ad10cb653bc2f44831b3cd0e790206322a4a3e5 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.android.ide.common.rendering.api.Bridge;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.intensive.RenderResult;
import com.android.layoutlib.bridge.intensive.RenderTestBase;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.layoutlib.bridge.intensive.util.ImageUtils;
import com.android.layoutlib.bridge.remote.client.RemoteBridgeClient;
import com.android.layoutlib.bridge.remote.server.ServerMain;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.rmi.NotBoundException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
public class RemoteBridgeTest extends RenderTestBase {
private ServerMain mServerMain;
private RemoteBridgeClient mClient;
/**
* Copy of RenderTestBase.renderAndVerify that allows using a different Bridge. TODO: Merge back
* into RenderTestBase
*/
protected static RenderResult renderAndVerify(Bridge bridge, SessionParams params,
String goldenFileName, long frameTimeNanos) throws ClassNotFoundException {
RenderResult result = RenderTestBase.render(bridge, params, frameTimeNanos);
try {
String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
assertNotNull(result.getImage());
ImageUtils.requireSimilar(goldenImagePath, result.getImage());
} catch (IOException e) {
getLogger().error(e, e.getMessage());
}
return result;
}
@Before
public void setupServer() throws IOException, NotBoundException, InterruptedException {
long startTime = System.currentTimeMillis();
mServerMain = ServerMain.forkAndStartServer(ServerMain.REGISTRY_BASE_PORT, 10);
mClient = RemoteBridgeClient.getRemoteBridge(mServerMain.getPort());
System.out.printf("Server started in %dms\n", System.currentTimeMillis() - startTime);
startTime = System.currentTimeMillis();
File data_dir = new File(PLATFORM_DIR, "data");
File res = new File(data_dir, "res");
File fontLocation = new File(data_dir, "fonts");
File buildProp = new File(PLATFORM_DIR, "build.prop");
File attrs = new File(res, "values" + File.separator + "attrs.xml");
mClient.init(ConfigGenerator.loadProperties(buildProp), fontLocation, null,
ConfigGenerator.getEnumMap(attrs), getLayoutLog());
System.out.printf("Remote client init took %dms\n",
System.currentTimeMillis() - startTime);
}
@After
public void stopServer() {
mClient.dispose();
mServerMain.stop();
}
/**
* Same test as RenderTest#testActivity but using the remote bridge
*/
@Test
public void testActivity() throws IOException, ClassNotFoundException {
SessionParams params = createSessionParams("activity.xml", ConfigGenerator.NEXUS_5);
RenderResult result = renderAndVerify(mClient, params, "activity.png", 250);
assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
if (result.getResult().getException() != null) {
result.getResult().getException().printStackTrace();
fail("Unexpected exception");
}
}
/**
* Same test as RenderTest#testActivity but using the remote bridge
*/
@Test
public void testCustomClassLoading() throws ClassNotFoundException {
LayoutLibTestCallback layoutLibCallback =
new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
layoutLibCallback.initResources();
LayoutPullParser parser = LayoutPullParser.createFromString(
"<CustomComponent xmlns:android=\"http://schemas" +
".android.com/apk/res/android\"\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\"\n>" +
"</CustomComponent>");
SessionParams params =
getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
"Theme.NoTitleBar", false).build();
RenderResult result = renderAndVerify(mClient, params, "remote_component_load.png", 250);
assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
if (result.getResult().getException() != null) {
result.getResult().getException().printStackTrace();
fail("Unexpected exception");
}
parser = LayoutPullParser.createFromString(
"<MissingCustomComponent xmlns:android=\"http://schemas" +
".android.com/apk/res/android\"\n" +
" android:layout_width=\"match_parent\"\n" +
" android:layout_height=\"match_parent\"\n>" +
"</MissingCustomComponent>");
params =
getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
"Theme.NoTitleBar", false).build();
result = renderAndVerify(mClient, params, "remote_component_load_fail.png", 250);
assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
if (result.getResult().getException() != null) {
result.getResult().getException().printStackTrace();
fail("Unexpected exception");
}
}
}