1 /* 2 * Copyright (C) 2022 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 enableLayoutValidator = false; 65 private boolean enableLayoutValidatorImageCheck = false; 66 private boolean transparentBackground = false; 67 68 @NonNull setParser(@onNull LayoutPullParser layoutParser)69 public SessionParamsBuilder setParser(@NonNull LayoutPullParser layoutParser) { 70 mLayoutParser = layoutParser; 71 72 return this; 73 } 74 75 @NonNull setRenderingMode(@onNull RenderingMode renderingMode)76 public SessionParamsBuilder setRenderingMode(@NonNull RenderingMode renderingMode) { 77 mRenderingMode = renderingMode; 78 return this; 79 } 80 81 @NonNull setConfigGenerator(@onNull ConfigGenerator configGenerator)82 public SessionParamsBuilder setConfigGenerator(@NonNull ConfigGenerator configGenerator) { 83 mConfigGenerator = configGenerator; 84 return this; 85 } 86 87 @NonNull setProjectResources(@onNull ResourceRepository resources)88 public SessionParamsBuilder setProjectResources(@NonNull ResourceRepository resources) { 89 mProjectResources = resources; 90 return this; 91 } 92 93 @NonNull setFrameworkResources(@onNull ResourceRepository resources)94 public SessionParamsBuilder setFrameworkResources(@NonNull ResourceRepository resources) { 95 mFrameworkResources = resources; 96 return this; 97 } 98 99 @NonNull setTheme(@onNull String themeName, boolean isProjectTheme)100 public SessionParamsBuilder setTheme(@NonNull String themeName, boolean isProjectTheme) { 101 mThemeName = themeName; 102 this.isProjectTheme = isProjectTheme; 103 return this; 104 } 105 106 @NonNull setTheme(@onNull String themeName)107 public SessionParamsBuilder setTheme(@NonNull String themeName) { 108 boolean isProjectTheme; 109 if (themeName.startsWith(SdkConstants.PREFIX_ANDROID)) { 110 themeName = themeName.substring(SdkConstants.PREFIX_ANDROID.length()); 111 isProjectTheme = false; 112 } else { 113 isProjectTheme = true; 114 } 115 return setTheme(themeName, isProjectTheme); 116 } 117 118 @NonNull setCallback(@onNull LayoutlibCallback callback)119 public SessionParamsBuilder setCallback(@NonNull LayoutlibCallback callback) { 120 mLayoutlibCallback = callback; 121 return this; 122 } 123 124 @NonNull setTargetSdk(int targetSdk)125 public SessionParamsBuilder setTargetSdk(int targetSdk) { 126 mTargetSdk = targetSdk; 127 return this; 128 } 129 130 @SuppressWarnings("unused") 131 @NonNull setMinSdk(int minSdk)132 public SessionParamsBuilder setMinSdk(int minSdk) { 133 mMinSdk = minSdk; 134 return this; 135 } 136 137 @NonNull setLayoutLog(@onNull ILayoutLog layoutLog)138 public SessionParamsBuilder setLayoutLog(@NonNull ILayoutLog layoutLog) { 139 mLayoutLog = layoutLog; 140 return this; 141 } 142 143 @NonNull setFlag(@onNull SessionParams.Key flag, Object value)144 public SessionParamsBuilder setFlag(@NonNull SessionParams.Key flag, Object value) { 145 mFlags.put(flag, value); 146 return this; 147 } 148 149 @NonNull setAssetRepository(@onNull AssetRepository repository)150 public SessionParamsBuilder setAssetRepository(@NonNull AssetRepository repository) { 151 mAssetRepository = repository; 152 return this; 153 } 154 155 @NonNull disableDecoration()156 public SessionParamsBuilder disableDecoration() { 157 mDecor = false; 158 return this; 159 } 160 161 @NonNull setImageFactory(@onNull IImageFactory imageFactory)162 public SessionParamsBuilder setImageFactory(@NonNull IImageFactory imageFactory) { 163 mImageFactory = imageFactory; 164 return this; 165 } 166 167 @NonNull enableLayoutValidation()168 public SessionParamsBuilder enableLayoutValidation() { 169 this.enableLayoutValidator = true; 170 return this; 171 } 172 173 @NonNull enableLayoutValidationImageCheck()174 public SessionParamsBuilder enableLayoutValidationImageCheck() { 175 this.enableLayoutValidatorImageCheck = true; 176 return this; 177 } 178 179 @NonNull setTransparentBackground()180 public SessionParamsBuilder setTransparentBackground() { 181 this.transparentBackground = true; 182 return this; 183 } 184 185 @NonNull build()186 public SessionParams build() { 187 assert mFrameworkResources != null; 188 assert mProjectResources != null; 189 assert mThemeName != null; 190 assert mLayoutLog != null; 191 assert mLayoutlibCallback != null; 192 193 FolderConfiguration config = mConfigGenerator.getFolderConfig(); 194 ResourceResolver resourceResolver = ResourceResolver.create( 195 ImmutableMap.of( 196 ResourceNamespace.ANDROID, mFrameworkResources.getConfiguredResources(config), 197 ResourceNamespace.TODO(), mProjectResources.getConfiguredResources(config)), 198 new ResourceReference( 199 ResourceNamespace.fromBoolean(!isProjectTheme), 200 ResourceType.STYLE, 201 mThemeName)); 202 203 SessionParams params = new SessionParams(mLayoutParser, mRenderingMode, mProjectKey /* for 204 caching */, mConfigGenerator.getHardwareConfig(), resourceResolver, mLayoutlibCallback, 205 mMinSdk, mTargetSdk, mLayoutLog); 206 params.setFlag(RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR, enableLayoutValidator); 207 params.setFlag( 208 RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR_IMAGE_CHECK, 209 enableLayoutValidatorImageCheck); 210 if (mImageFactory != null) { 211 params.setImageFactory(mImageFactory); 212 } 213 214 mFlags.forEach(params::setFlag); 215 params.setAssetRepository(mAssetRepository); 216 217 if (!mDecor) { 218 params.setForceNoDecor(); 219 } 220 221 if (transparentBackground) { 222 params.setTransparentBackground(); 223 } 224 225 return params; 226 } 227 } 228