• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import com.android.ide.common.rendering.api.Bridge;
18 import com.android.ide.common.rendering.api.Result;
19 import com.android.ide.common.rendering.api.SessionParams;
20 import com.android.layoutlib.bridge.intensive.RenderResult;
21 import com.android.layoutlib.bridge.intensive.RenderTestBase;
22 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
23 import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
24 import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
25 import com.android.layoutlib.bridge.intensive.util.ImageUtils;
26 import com.android.layoutlib.bridge.remote.client.RemoteBridgeClient;
27 import com.android.layoutlib.bridge.remote.server.ServerMain;
28 
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 
33 import java.io.File;
34 import java.io.IOException;
35 import java.rmi.NotBoundException;
36 
37 import static org.junit.Assert.assertEquals;
38 import static org.junit.Assert.assertNotNull;
39 import static org.junit.Assert.fail;
40 
41 
42 public class RemoteBridgeTest extends RenderTestBase {
43     private ServerMain mServerMain;
44     private RemoteBridgeClient mClient;
45 
46     /**
47      * Copy of RenderTestBase.renderAndVerify that allows using a different Bridge. TODO: Merge back
48      * into RenderTestBase
49      */
renderAndVerify(Bridge bridge, SessionParams params, String goldenFileName, long frameTimeNanos)50     protected static RenderResult renderAndVerify(Bridge bridge, SessionParams params,
51             String goldenFileName, long frameTimeNanos) throws ClassNotFoundException {
52         RenderResult result = RenderTestBase.render(bridge, params, frameTimeNanos);
53         try {
54             String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
55             assertNotNull(result.getImage());
56             ImageUtils.requireSimilar(goldenImagePath, result.getImage());
57         } catch (IOException e) {
58             getLogger().error(e, e.getMessage());
59         }
60 
61         return result;
62     }
63 
64     @Before
setupServer()65     public void setupServer() throws IOException, NotBoundException, InterruptedException {
66         long startTime = System.currentTimeMillis();
67         mServerMain = ServerMain.forkAndStartServer(ServerMain.REGISTRY_BASE_PORT, 10);
68         mClient = RemoteBridgeClient.getRemoteBridge(mServerMain.getPort());
69         System.out.printf("Server started in %dms\n", System.currentTimeMillis() - startTime);
70         startTime = System.currentTimeMillis();
71 
72         File data_dir = new File(PLATFORM_DIR, "data");
73         File res = new File(data_dir, "res");
74         File fontLocation = new File(data_dir, "fonts");
75         File buildProp = new File(PLATFORM_DIR, "build.prop");
76         File attrs = new File(res, "values" + File.separator + "attrs.xml");
77 
78         mClient.init(ConfigGenerator.loadProperties(buildProp), fontLocation, null,
79                 ConfigGenerator.getEnumMap(attrs), getLayoutLog());
80         System.out.printf("Remote client init took %dms\n",
81                 System.currentTimeMillis() - startTime);
82     }
83 
84     @After
stopServer()85     public void stopServer() {
86         mClient.dispose();
87         mServerMain.stop();
88     }
89 
90     /**
91      * Same test as RenderTest#testActivity but using the remote bridge
92      */
93     @Test
testActivity()94     public void testActivity() throws IOException, ClassNotFoundException {
95         SessionParams params = createSessionParams("activity.xml", ConfigGenerator.NEXUS_5);
96         RenderResult result = renderAndVerify(mClient, params, "activity.png", 250);
97         assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
98         if (result.getResult().getException() != null) {
99             result.getResult().getException().printStackTrace();
100             fail("Unexpected exception");
101         }
102     }
103 
104     /**
105      * Same test as RenderTest#testActivity but using the remote bridge
106      */
107     @Test
testCustomClassLoading()108     public void testCustomClassLoading() throws ClassNotFoundException {
109         LayoutLibTestCallback layoutLibCallback =
110                 new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
111         layoutLibCallback.initResources();
112 
113         LayoutPullParser parser = LayoutPullParser.createFromString(
114                 "<CustomComponent xmlns:android=\"http://schemas" +
115                         ".android.com/apk/res/android\"\n" +
116                         "                android:layout_width=\"match_parent\"\n" +
117                         "                android:layout_height=\"match_parent\"\n>" +
118                         "</CustomComponent>");
119         SessionParams params =
120                 getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
121                         "Theme.NoTitleBar", false).build();
122 
123         RenderResult result = renderAndVerify(mClient, params, "remote_component_load.png", 250);
124         assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
125         if (result.getResult().getException() != null) {
126             result.getResult().getException().printStackTrace();
127             fail("Unexpected exception");
128         }
129 
130         parser = LayoutPullParser.createFromString(
131                 "<MissingCustomComponent xmlns:android=\"http://schemas" +
132                         ".android.com/apk/res/android\"\n" +
133                         "                android:layout_width=\"match_parent\"\n" +
134                         "                android:layout_height=\"match_parent\"\n>" +
135                         "</MissingCustomComponent>");
136         params =
137                 getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
138                         "Theme.NoTitleBar", false).build();
139         result = renderAndVerify(mClient, params, "remote_component_load_fail.png", 250);
140         assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
141         if (result.getResult().getException() != null) {
142             result.getResult().getException().printStackTrace();
143             fail("Unexpected exception");
144         }
145     }
146 }