1 /* 2 * Copyright (C) 2014 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.setup; 18 19 import com.android.ide.common.rendering.api.HardwareConfig; 20 import com.android.ide.common.resources.configuration.CountryCodeQualifier; 21 import com.android.ide.common.resources.configuration.DensityQualifier; 22 import com.android.ide.common.resources.configuration.FolderConfiguration; 23 import com.android.ide.common.resources.configuration.KeyboardStateQualifier; 24 import com.android.ide.common.resources.configuration.LayoutDirectionQualifier; 25 import com.android.ide.common.resources.configuration.LocaleQualifier; 26 import com.android.ide.common.resources.configuration.NavigationMethodQualifier; 27 import com.android.ide.common.resources.configuration.NetworkCodeQualifier; 28 import com.android.ide.common.resources.configuration.NightModeQualifier; 29 import com.android.ide.common.resources.configuration.ScreenDimensionQualifier; 30 import com.android.ide.common.resources.configuration.ScreenOrientationQualifier; 31 import com.android.ide.common.resources.configuration.ScreenRatioQualifier; 32 import com.android.ide.common.resources.configuration.ScreenSizeQualifier; 33 import com.android.ide.common.resources.configuration.TextInputMethodQualifier; 34 import com.android.ide.common.resources.configuration.TouchScreenQualifier; 35 import com.android.ide.common.resources.configuration.UiModeQualifier; 36 import com.android.ide.common.resources.configuration.VersionQualifier; 37 import com.android.resources.Density; 38 import com.android.resources.Keyboard; 39 import com.android.resources.KeyboardState; 40 import com.android.resources.Navigation; 41 import com.android.resources.NightMode; 42 import com.android.resources.ScreenOrientation; 43 import com.android.resources.ScreenRatio; 44 import com.android.resources.ScreenSize; 45 import com.android.resources.TouchScreen; 46 import com.android.resources.UiMode; 47 48 import org.xmlpull.v1.XmlPullParser; 49 import org.xmlpull.v1.XmlPullParserException; 50 import org.xmlpull.v1.XmlPullParserFactory; 51 52 import java.io.File; 53 import java.io.FileInputStream; 54 import java.io.IOException; 55 import java.util.Map; 56 import java.util.Properties; 57 58 import com.google.android.collect.Maps; 59 60 /** 61 * Provides {@link FolderConfiguration} and {@link HardwareConfig} for various devices. Also 62 * provides utility methods to parse build.prop and attrs.xml to generate the appropriate maps. 63 */ 64 @SuppressWarnings("UnusedDeclaration") // For the pre-configured nexus generators. 65 public class ConfigGenerator { 66 67 public static final ConfigGenerator NEXUS_4 = new ConfigGenerator(); 68 69 public static final ConfigGenerator NEXUS_5 = new ConfigGenerator() 70 .setScreenHeight(1920) 71 .setScreenWidth(1080) 72 .setXdpi(445) 73 .setYdpi(445) 74 .setOrientation(ScreenOrientation.PORTRAIT) 75 .setDensity(Density.XXHIGH) 76 .setRatio(ScreenRatio.NOTLONG) 77 .setSize(ScreenSize.NORMAL) 78 .setKeyboard(Keyboard.NOKEY) 79 .setTouchScreen(TouchScreen.FINGER) 80 .setKeyboardState(KeyboardState.SOFT) 81 .setSoftButtons(true) 82 .setNavigation(Navigation.NONAV); 83 84 public static final ConfigGenerator NEXUS_7 = new ConfigGenerator() 85 .setScreenHeight(1920) 86 .setScreenWidth(1200) 87 .setXdpi(323) 88 .setYdpi(323) 89 .setOrientation(ScreenOrientation.PORTRAIT) 90 .setDensity(Density.XHIGH) 91 .setRatio(ScreenRatio.NOTLONG) 92 .setSize(ScreenSize.LARGE) 93 .setKeyboard(Keyboard.NOKEY) 94 .setTouchScreen(TouchScreen.FINGER) 95 .setKeyboardState(KeyboardState.SOFT) 96 .setSoftButtons(true) 97 .setNavigation(Navigation.NONAV); 98 99 public static final ConfigGenerator NEXUS_10 = new ConfigGenerator() 100 .setScreenHeight(1600) 101 .setScreenWidth(2560) 102 .setXdpi(300) 103 .setYdpi(300) 104 .setOrientation(ScreenOrientation.LANDSCAPE) 105 .setDensity(Density.XHIGH) 106 .setRatio(ScreenRatio.NOTLONG) 107 .setSize(ScreenSize.XLARGE) 108 .setKeyboard(Keyboard.NOKEY) 109 .setTouchScreen(TouchScreen.FINGER) 110 .setKeyboardState(KeyboardState.SOFT) 111 .setSoftButtons(true) 112 .setNavigation(Navigation.NONAV); 113 114 public static final ConfigGenerator NEXUS_5_LAND = new ConfigGenerator() 115 .setScreenHeight(1080) 116 .setScreenWidth(1920) 117 .setXdpi(445) 118 .setYdpi(445) 119 .setOrientation(ScreenOrientation.LANDSCAPE) 120 .setDensity(Density.XXHIGH) 121 .setRatio(ScreenRatio.NOTLONG) 122 .setSize(ScreenSize.NORMAL) 123 .setKeyboard(Keyboard.NOKEY) 124 .setTouchScreen(TouchScreen.FINGER) 125 .setKeyboardState(KeyboardState.SOFT) 126 .setSoftButtons(true) 127 .setNavigation(Navigation.NONAV); 128 129 public static final ConfigGenerator NEXUS_7_2012 = new ConfigGenerator() 130 .setScreenHeight(1280) 131 .setScreenWidth(800) 132 .setXdpi(195) 133 .setYdpi(200) 134 .setOrientation(ScreenOrientation.PORTRAIT) 135 .setDensity(Density.TV) 136 .setRatio(ScreenRatio.NOTLONG) 137 .setSize(ScreenSize.LARGE) 138 .setKeyboard(Keyboard.NOKEY) 139 .setTouchScreen(TouchScreen.FINGER) 140 .setKeyboardState(KeyboardState.SOFT) 141 .setSoftButtons(true) 142 .setNavigation(Navigation.NONAV); 143 144 private static final String TAG_ATTR = "attr"; 145 private static final String TAG_ENUM = "enum"; 146 private static final String TAG_FLAG = "flag"; 147 private static final String ATTR_NAME = "name"; 148 private static final String ATTR_VALUE = "value"; 149 150 // Device Configuration. Defaults are for a Nexus 4 device. 151 private int mScreenHeight = 1280; 152 private int mScreenWidth = 768; 153 private int mXdpi = 320; 154 private int mYdpi = 320; 155 private ScreenOrientation mOrientation = ScreenOrientation.PORTRAIT; 156 private Density mDensity = Density.XHIGH; 157 private ScreenRatio mRatio = ScreenRatio.NOTLONG; 158 private ScreenSize mSize = ScreenSize.NORMAL; 159 private Keyboard mKeyboard = Keyboard.NOKEY; 160 private TouchScreen mTouchScreen = TouchScreen.FINGER; 161 private KeyboardState mKeyboardState = KeyboardState.SOFT; 162 private boolean mSoftButtons = true; 163 private Navigation mNavigation = Navigation.NONAV; 164 getFolderConfig()165 public FolderConfiguration getFolderConfig() { 166 FolderConfiguration config = FolderConfiguration.createDefault(); 167 config.setDensityQualifier(new DensityQualifier(mDensity)); 168 config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation)); 169 if (mScreenWidth > mScreenHeight) { 170 config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth, 171 mScreenHeight)); 172 } else { 173 config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight, 174 mScreenWidth)); 175 } 176 config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio)); 177 config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize)); 178 config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard)); 179 config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen)); 180 config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState)); 181 config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation)); 182 183 config.updateScreenWidthAndHeight(); 184 185 // some default qualifiers. 186 config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL)); 187 config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT)); 188 config.setCountryCodeQualifier(new CountryCodeQualifier()); 189 config.setLayoutDirectionQualifier(new LayoutDirectionQualifier()); 190 config.setNetworkCodeQualifier(new NetworkCodeQualifier()); 191 config.setLocaleQualifier(new LocaleQualifier()); 192 config.setVersionQualifier(new VersionQualifier()); 193 return config; 194 } 195 getHardwareConfig()196 public HardwareConfig getHardwareConfig() { 197 return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize, 198 mOrientation, null, mSoftButtons); 199 } 200 loadProperties(File path)201 public static Map<String, String> loadProperties(File path) { 202 Properties p = new Properties(); 203 Map<String, String> map = Maps.newHashMap(); 204 try { 205 p.load(new FileInputStream(path)); 206 for (String key : p.stringPropertyNames()) { 207 map.put(key, p.getProperty(key)); 208 } 209 } catch (IOException e) { 210 e.printStackTrace(); 211 } 212 return map; 213 } 214 getEnumMap(File path)215 public static Map<String, Map<String, Integer>> getEnumMap(File path) { 216 Map<String, Map<String, Integer>> map = Maps.newHashMap(); 217 try { 218 XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); 219 xmlPullParser.setInput(new FileInputStream(path), null); 220 int eventType = xmlPullParser.getEventType(); 221 String attr = null; 222 while (eventType != XmlPullParser.END_DOCUMENT) { 223 if (eventType == XmlPullParser.START_TAG) { 224 if (TAG_ATTR.equals(xmlPullParser.getName())) { 225 attr = xmlPullParser.getAttributeValue(null, ATTR_NAME); 226 } else if (TAG_ENUM.equals(xmlPullParser.getName()) 227 || TAG_FLAG.equals(xmlPullParser.getName())) { 228 String name = xmlPullParser.getAttributeValue(null, ATTR_NAME); 229 String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE); 230 // Integer.decode cannot handle "ffffffff", see JDK issue 6624867 231 int i = (int) (long) Long.decode(value); 232 assert attr != null; 233 Map<String, Integer> attributeMap = map.get(attr); 234 if (attributeMap == null) { 235 attributeMap = Maps.newHashMap(); 236 map.put(attr, attributeMap); 237 } 238 attributeMap.put(name, i); 239 } 240 } else if (eventType == XmlPullParser.END_TAG) { 241 if (TAG_ATTR.equals(xmlPullParser.getName())) { 242 attr = null; 243 } 244 } 245 eventType = xmlPullParser.next(); 246 } 247 } catch (XmlPullParserException e) { 248 e.printStackTrace(); 249 } catch (IOException e) { 250 e.printStackTrace(); 251 } 252 return map; 253 } 254 255 // Methods to set the configuration values. 256 setScreenHeight(int height)257 public ConfigGenerator setScreenHeight(int height) { 258 mScreenHeight = height; 259 return this; 260 } 261 setScreenWidth(int width)262 public ConfigGenerator setScreenWidth(int width) { 263 mScreenWidth = width; 264 return this; 265 } 266 setXdpi(int xdpi)267 public ConfigGenerator setXdpi(int xdpi) { 268 mXdpi = xdpi; 269 return this; 270 } 271 setYdpi(int ydpi)272 public ConfigGenerator setYdpi(int ydpi) { 273 mYdpi = ydpi; 274 return this; 275 } 276 setOrientation(ScreenOrientation orientation)277 public ConfigGenerator setOrientation(ScreenOrientation orientation) { 278 mOrientation = orientation; 279 return this; 280 } 281 setDensity(Density density)282 public ConfigGenerator setDensity(Density density) { 283 mDensity = density; 284 return this; 285 } 286 setRatio(ScreenRatio ratio)287 public ConfigGenerator setRatio(ScreenRatio ratio) { 288 mRatio = ratio; 289 return this; 290 } 291 setSize(ScreenSize size)292 public ConfigGenerator setSize(ScreenSize size) { 293 mSize = size; 294 return this; 295 } 296 setKeyboard(Keyboard keyboard)297 public ConfigGenerator setKeyboard(Keyboard keyboard) { 298 mKeyboard = keyboard; 299 return this; 300 } 301 setTouchScreen(TouchScreen touchScreen)302 public ConfigGenerator setTouchScreen(TouchScreen touchScreen) { 303 mTouchScreen = touchScreen; 304 return this; 305 } 306 setKeyboardState(KeyboardState state)307 public ConfigGenerator setKeyboardState(KeyboardState state) { 308 mKeyboardState = state; 309 return this; 310 } 311 setSoftButtons(boolean softButtons)312 public ConfigGenerator setSoftButtons(boolean softButtons) { 313 mSoftButtons = softButtons; 314 return this; 315 } 316 setNavigation(Navigation navigation)317 public ConfigGenerator setNavigation(Navigation navigation) { 318 mNavigation = navigation; 319 return this; 320 } 321 } 322