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 package com.android.layoutlib.bridge.intensive.util;
18 
19 import com.android.SdkConstants;
20 import com.android.ide.common.rendering.api.AssetRepository;
21 import com.android.ide.common.rendering.api.IImageFactory;
22 import com.android.ide.common.rendering.api.ILayoutLog;
23 import com.android.ide.common.rendering.api.LayoutlibCallback;
24 import com.android.ide.common.rendering.api.ResourceNamespace;
25 import com.android.ide.common.rendering.api.ResourceReference;
26 import com.android.ide.common.rendering.api.SessionParams;
27 import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
28 import com.android.ide.common.resources.ResourceResolver;
29 import com.android.ide.common.resources.configuration.FolderConfiguration;
30 import com.android.ide.common.resources.deprecated.ResourceRepository;
31 import com.android.layoutlib.bridge.android.RenderParamsFlags;
32 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
33 import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
34 import com.android.resources.ResourceType;
35 
36 import android.annotation.NonNull;
37 
38 import java.util.HashMap;
39 import java.util.Map;
40 
41 import com.google.common.collect.ImmutableMap;
42 
43 /**
44  * Builder to help setting up {@link SessionParams} objects.
45  */
46 public class SessionParamsBuilder {
47 
48     private LayoutPullParser mLayoutParser;
49     private RenderingMode mRenderingMode = RenderingMode.NORMAL;
50     private Object mProjectKey = null;
51     private ConfigGenerator mConfigGenerator = ConfigGenerator.NEXUS_5;
52     private ResourceRepository mFrameworkResources;
53     private ResourceRepository mProjectResources;
54     private String mThemeName;
55     private boolean isProjectTheme;
56     private LayoutlibCallback mLayoutlibCallback;
57     private int mTargetSdk;
58     private int mMinSdk = 0;
59     private ILayoutLog mLayoutLog;
60     private Map<SessionParams.Key, Object> mFlags = new HashMap<>();
61     private AssetRepository mAssetRepository = null;
62     private boolean mDecor = true;
63     private IImageFactory mImageFactory = null;
64     private boolean enableShadows = true;
65     private boolean highQualityShadows = true;
66     private boolean enableLayoutValidator = false;
67     private boolean enableLayoutValidatorImageCheck = false;
68 
69     @NonNull
setParser(@onNull LayoutPullParser layoutParser)70     public SessionParamsBuilder setParser(@NonNull LayoutPullParser layoutParser) {
71         mLayoutParser = layoutParser;
72 
73         return this;
74     }
75 
76     @NonNull
setRenderingMode(@onNull RenderingMode renderingMode)77     public SessionParamsBuilder setRenderingMode(@NonNull RenderingMode renderingMode) {
78         mRenderingMode = renderingMode;
79         return this;
80     }
81 
82     @NonNull
setConfigGenerator(@onNull ConfigGenerator configGenerator)83     public SessionParamsBuilder setConfigGenerator(@NonNull ConfigGenerator configGenerator) {
84         mConfigGenerator = configGenerator;
85         return this;
86     }
87 
88     @NonNull
setProjectResources(@onNull ResourceRepository resources)89     public SessionParamsBuilder setProjectResources(@NonNull ResourceRepository resources) {
90         mProjectResources = resources;
91         return this;
92     }
93 
94     @NonNull
setFrameworkResources(@onNull ResourceRepository resources)95     public SessionParamsBuilder setFrameworkResources(@NonNull ResourceRepository resources) {
96         mFrameworkResources = resources;
97         return this;
98     }
99 
100     @NonNull
setTheme(@onNull String themeName, boolean isProjectTheme)101     public SessionParamsBuilder setTheme(@NonNull String themeName, boolean isProjectTheme) {
102         mThemeName = themeName;
103         this.isProjectTheme = isProjectTheme;
104         return this;
105     }
106 
107     @NonNull
setTheme(@onNull String themeName)108     public SessionParamsBuilder setTheme(@NonNull String themeName) {
109         boolean isProjectTheme;
110         if (themeName.startsWith(SdkConstants.PREFIX_ANDROID)) {
111             themeName = themeName.substring(SdkConstants.PREFIX_ANDROID.length());
112             isProjectTheme = false;
113         } else {
114             isProjectTheme = true;
115         }
116         return setTheme(themeName, isProjectTheme);
117     }
118 
119     @NonNull
setCallback(@onNull LayoutlibCallback callback)120     public SessionParamsBuilder setCallback(@NonNull LayoutlibCallback callback) {
121         mLayoutlibCallback = callback;
122         return this;
123     }
124 
125     @NonNull
setTargetSdk(int targetSdk)126     public SessionParamsBuilder setTargetSdk(int targetSdk) {
127         mTargetSdk = targetSdk;
128         return this;
129     }
130 
131     @SuppressWarnings("unused")
132     @NonNull
setMinSdk(int minSdk)133     public SessionParamsBuilder setMinSdk(int minSdk) {
134         mMinSdk = minSdk;
135         return this;
136     }
137 
138     @NonNull
setLayoutLog(@onNull ILayoutLog layoutLog)139     public SessionParamsBuilder setLayoutLog(@NonNull ILayoutLog layoutLog) {
140         mLayoutLog = layoutLog;
141         return this;
142     }
143 
144     @NonNull
setFlag(@onNull SessionParams.Key flag, Object value)145     public SessionParamsBuilder setFlag(@NonNull SessionParams.Key flag, Object value) {
146         mFlags.put(flag, value);
147         return this;
148     }
149 
150     @NonNull
setAssetRepository(@onNull AssetRepository repository)151     public SessionParamsBuilder setAssetRepository(@NonNull AssetRepository repository) {
152         mAssetRepository = repository;
153         return this;
154     }
155 
156     @NonNull
disableDecoration()157     public SessionParamsBuilder disableDecoration() {
158         mDecor = false;
159         return this;
160     }
161 
162     @NonNull
setImageFactory(@onNull IImageFactory imageFactory)163     public SessionParamsBuilder setImageFactory(@NonNull IImageFactory imageFactory) {
164         mImageFactory = imageFactory;
165         return this;
166     }
167 
168     @NonNull
disableShadows()169     public SessionParamsBuilder disableShadows() {
170         this.enableShadows = false;
171         return this;
172     }
173 
174     @NonNull
disableHighQualityShadows()175     public SessionParamsBuilder disableHighQualityShadows() {
176         this.highQualityShadows = false;
177         return this;
178     }
179 
180     @NonNull
enableLayoutValidation()181     public SessionParamsBuilder enableLayoutValidation() {
182         this.enableLayoutValidator = true;
183         return this;
184     }
185 
186     @NonNull
enableLayoutValidationImageCheck()187     public SessionParamsBuilder enableLayoutValidationImageCheck() {
188         this.enableLayoutValidatorImageCheck = true;
189         return this;
190     }
191 
192     @NonNull
build()193     public SessionParams build() {
194         assert mFrameworkResources != null;
195         assert mProjectResources != null;
196         assert mThemeName != null;
197         assert mLayoutLog != null;
198         assert mLayoutlibCallback != null;
199 
200         FolderConfiguration config = mConfigGenerator.getFolderConfig();
201         ResourceResolver resourceResolver = ResourceResolver.create(
202                 ImmutableMap.of(
203                         ResourceNamespace.ANDROID, mFrameworkResources.getConfiguredResources(config),
204                         ResourceNamespace.TODO(), mProjectResources.getConfiguredResources(config)),
205                 new ResourceReference(
206                         ResourceNamespace.fromBoolean(!isProjectTheme),
207                         ResourceType.STYLE,
208                         mThemeName));
209 
210         SessionParams params = new SessionParams(mLayoutParser, mRenderingMode, mProjectKey /* for
211         caching */, mConfigGenerator.getHardwareConfig(), resourceResolver, mLayoutlibCallback,
212                 mMinSdk, mTargetSdk, mLayoutLog);
213         params.setFlag(RenderParamsFlags.FLAG_ENABLE_SHADOW, enableShadows);
214         params.setFlag(RenderParamsFlags.FLAG_RENDER_HIGH_QUALITY_SHADOW, highQualityShadows);
215         params.setFlag(RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR, enableLayoutValidator);
216         params.setFlag(
217                 RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR_IMAGE_CHECK,
218                 enableLayoutValidatorImageCheck);
219         if (mImageFactory != null) {
220             params.setImageFactory(mImageFactory);
221         }
222 
223         mFlags.forEach(params::setFlag);
224         params.setAssetRepository(mAssetRepository);
225 
226         if (!mDecor) {
227             params.setForceNoDecor();
228         }
229 
230         return params;
231     }
232 }
233