1 /*
2  * Copyright (C) 2018 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 package com.android.layoutlib.bridge.android;
18 
19 import com.android.ide.common.rendering.api.SessionParams;
20 import com.android.layoutlib.bridge.impl.RenderAction;
21 import com.android.layoutlib.bridge.impl.RenderActionTestUtil;
22 import com.android.layoutlib.bridge.intensive.RenderTestBase;
23 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
24 import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
25 import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
26 
27 import org.junit.Test;
28 
29 import android.R.attr;
30 import android.R.style;
31 import android.content.Context;
32 import android.content.res.Configuration;
33 import android.content.res.TypedArray;
34 import android.util.DisplayMetrics;
35 import android.view.ContextThemeWrapper;
36 
37 import static org.junit.Assert.assertTrue;
38 
39 public class BridgeContextTest extends RenderTestBase {
40     @Test
basic()41     public void basic() throws ClassNotFoundException {
42         // Setup
43         // Create the layout pull parser for our resources (empty.xml can not be part of the test
44         // app as it won't compile).
45         LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
46         // Create LayoutLibCallback.
47         LayoutLibTestCallback layoutLibCallback =
48                 new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
49         layoutLibCallback.initResources();
50         SessionParams params = getSessionParamsBuilder()
51                 .setParser(parser)
52                 .setCallback(layoutLibCallback)
53                 .setTheme("Theme.Material", false)
54                 .build();
55         DisplayMetrics metrics = new DisplayMetrics();
56         Configuration configuration = RenderAction.getConfiguration(params);
57         BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
58                 params.getAssets(), params.getLayoutlibCallback(), configuration,
59                 params.getTargetSdkVersion(), params.isRtlSupported(), true, true);
60 
61         context.initResources();
62         BridgeContext oldContext = RenderActionTestUtil.setBridgeContext(context);
63         try {
64             Context themeContext = new ContextThemeWrapper(context, style.Theme_Material);
65             // First we try to get the style from the ?attr/editTextStyle fallback value.
66             // We pass an invalid value to defStyleRes
67             TypedArray array = themeContext.obtainStyledAttributes(null,
68                             new int[]{attr.clickable}, attr.editTextStyle, Integer.MAX_VALUE);
69             assertTrue(array.getBoolean(0, false));
70             // Now, we try to get it directly from the Widget.EditText. We pass an invalid value
71             // to defStyleAttr so it fails and falls back to the defStyleRes
72             array = themeContext.obtainStyledAttributes(null,
73                     new int[]{attr.clickable}, Integer.MAX_VALUE,
74                     style.Widget_EditText);
75             assertTrue(array.getBoolean(0, false));
76 
77         } finally {
78             RenderActionTestUtil.setBridgeContext(oldContext);
79             context.disposeResources();
80         }
81 
82         // This message is expected when asking for an invalid defStyleAttr
83         sRenderMessages.removeIf(msg ->
84                 msg.startsWith("Failed to find the style corresponding to the id"));
85     }
86 
87     @Test
checkNoErrorWhenUsingDefaults()88     public void checkNoErrorWhenUsingDefaults() throws ClassNotFoundException {
89         // Setup
90         // Create the layout pull parser for our resources (empty.xml can not be part of the test
91         // app as it won't compile).
92         LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
93         // Create LayoutLibCallback.
94         LayoutLibTestCallback layoutLibCallback =
95                 new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
96         layoutLibCallback.initResources();
97         SessionParams params = getSessionParamsBuilder()
98                 .setParser(parser)
99                 .setCallback(layoutLibCallback)
100                 .setTheme("Theme.Material", false)
101                 .build();
102         DisplayMetrics metrics = new DisplayMetrics();
103         Configuration configuration = RenderAction.getConfiguration(params);
104         BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
105                 params.getAssets(), params.getLayoutlibCallback(), configuration,
106                 params.getTargetSdkVersion(), params.isRtlSupported(), true, true);
107 
108         context.initResources();
109         BridgeContext oldContext = RenderActionTestUtil.setBridgeContext(context);
110         try {
111             Context themeContext = new ContextThemeWrapper(context, style.Theme_Material);
112             // First we try to get the style from the ?attr/editTextStyle fallback value.
113             // We pass an invalid value to defStyleRes
114             themeContext.obtainStyledAttributes(null,
115                     new int[]{attr.clickable}, 0, style.Widget_EditText);
116             themeContext.obtainStyledAttributes(null,
117                     new int[]{attr.clickable}, attr.editTextStyle, 0);
118         } finally {
119             RenderActionTestUtil.setBridgeContext(oldContext);
120             context.disposeResources();
121         }
122 
123 
124     }
125 }
126