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 android.annotation.NonNull; 20 21 import com.android.SdkConstants; 22 import com.android.ide.common.rendering.api.AssetRepository; 23 import com.android.ide.common.rendering.api.IImageFactory; 24 import com.android.ide.common.rendering.api.ILayoutLog; 25 import com.android.ide.common.rendering.api.LayoutlibCallback; 26 import com.android.ide.common.rendering.api.ResourceNamespace; 27 import com.android.ide.common.rendering.api.ResourceReference; 28 import com.android.ide.common.rendering.api.SessionParams; 29 import com.android.ide.common.rendering.api.SessionParams.RenderingMode; 30 import com.android.ide.common.resources.ResourceRepository; 31 import com.android.ide.common.resources.ResourceRepositoryUtil; 32 import com.android.ide.common.resources.ResourceResolver; 33 import com.android.ide.common.resources.ResourceValueMap; 34 import com.android.ide.common.resources.configuration.FolderConfiguration; 35 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator; 36 import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser; 37 import com.android.resources.ResourceType; 38 39 import com.google.common.collect.Table; 40 41 import java.util.HashMap; 42 import java.util.Map; 43 44 /** 45 * Builder to help setting up {@link SessionParams} objects. 46 */ 47 public class SessionParamsBuilder { 48 49 private LayoutPullParser mLayoutParser; 50 private RenderingMode mRenderingMode = RenderingMode.NORMAL; 51 private Object mProjectKey = null; 52 private ConfigGenerator mConfigGenerator = ConfigGenerator.NEXUS_5; 53 private ResourceRepository mFrameworkResources; 54 private ResourceRepository mProjectResources; 55 private String mThemeName; 56 private boolean isProjectTheme; 57 private LayoutlibCallback mLayoutlibCallback; 58 private int mTargetSdk; 59 private int mMinSdk = 0; 60 private ILayoutLog mLayoutLog; 61 private Map<SessionParams.Key, Object> mFlags = new HashMap<>(); 62 private AssetRepository mAssetRepository = null; 63 private boolean mDecor = true; 64 private IImageFactory mImageFactory = null; 65 private boolean enableLayoutValidator = 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 setTransparentBackground()174 public SessionParamsBuilder setTransparentBackground() { 175 this.transparentBackground = true; 176 return this; 177 } 178 179 @NonNull build()180 public SessionParams build() { 181 assert mFrameworkResources != null; 182 assert mProjectResources != null; 183 assert mThemeName != null; 184 assert mLayoutLog != null; 185 assert mLayoutlibCallback != null; 186 187 FolderConfiguration config = mConfigGenerator.getFolderConfig(); 188 Map<ResourceType, ResourceValueMap> frameworkConfigResources = 189 ResourceRepositoryUtil.getConfiguredResources(mFrameworkResources, config) 190 .row(ResourceNamespace.ANDROID); 191 Table<ResourceNamespace, ResourceType, ResourceValueMap> projectConfigResources = 192 ResourceRepositoryUtil.getConfiguredResources(mProjectResources, config); 193 Map<ResourceNamespace, Map<ResourceType, ResourceValueMap>> allResourcesMap = 194 new HashMap<>(); 195 allResourcesMap.put(ResourceNamespace.ANDROID, frameworkConfigResources); 196 for (ResourceNamespace namespace : projectConfigResources.rowKeySet()) { 197 allResourcesMap.put(namespace, projectConfigResources.row(namespace)); 198 } 199 ResourceResolver resourceResolver = 200 ResourceResolver.create( 201 allResourcesMap, 202 new ResourceReference( 203 ResourceNamespace.fromBoolean(!isProjectTheme), 204 ResourceType.STYLE, 205 mThemeName)); 206 207 SessionParams params = new SessionParams(mLayoutParser, mRenderingMode, mProjectKey /* for 208 caching */, mConfigGenerator.getHardwareConfig(), resourceResolver, mLayoutlibCallback, 209 mMinSdk, mTargetSdk, mLayoutLog); 210 params.setLayoutValidationChecker(() -> enableLayoutValidator); 211 if (mImageFactory != null) { 212 params.setImageFactory(mImageFactory); 213 } 214 215 mFlags.forEach(params::setFlag); 216 params.setAssetRepository(mAssetRepository); 217 218 if (!mDecor) { 219 params.setForceNoDecor(); 220 } 221 222 if (transparentBackground) { 223 params.setTransparentBackground(); 224 } 225 226 return params; 227 } 228 } 229