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 17package com.android.layoutlib.bridge.intensive.setup; 18 19import com.android.ide.common.rendering.api.HardwareConfig; 20import com.android.ide.common.resources.configuration.CountryCodeQualifier; 21import com.android.ide.common.resources.configuration.DensityQualifier; 22import com.android.ide.common.resources.configuration.FolderConfiguration; 23import com.android.ide.common.resources.configuration.KeyboardStateQualifier; 24import com.android.ide.common.resources.configuration.LayoutDirectionQualifier; 25import com.android.ide.common.resources.configuration.LocaleQualifier; 26import com.android.ide.common.resources.configuration.NavigationMethodQualifier; 27import com.android.ide.common.resources.configuration.NetworkCodeQualifier; 28import com.android.ide.common.resources.configuration.NightModeQualifier; 29import com.android.ide.common.resources.configuration.ScreenDimensionQualifier; 30import com.android.ide.common.resources.configuration.ScreenOrientationQualifier; 31import com.android.ide.common.resources.configuration.ScreenRatioQualifier; 32import com.android.ide.common.resources.configuration.ScreenSizeQualifier; 33import com.android.ide.common.resources.configuration.TextInputMethodQualifier; 34import com.android.ide.common.resources.configuration.TouchScreenQualifier; 35import com.android.ide.common.resources.configuration.UiModeQualifier; 36import com.android.ide.common.resources.configuration.VersionQualifier; 37import com.android.resources.Density; 38import com.android.resources.Keyboard; 39import com.android.resources.KeyboardState; 40import com.android.resources.Navigation; 41import com.android.resources.NightMode; 42import com.android.resources.ScreenOrientation; 43import com.android.resources.ScreenRatio; 44import com.android.resources.ScreenSize; 45import com.android.resources.TouchScreen; 46import com.android.resources.UiMode; 47 48import org.xmlpull.v1.XmlPullParser; 49import org.xmlpull.v1.XmlPullParserException; 50import org.xmlpull.v1.XmlPullParserFactory; 51 52import java.io.File; 53import java.io.FileInputStream; 54import java.io.IOException; 55import java.util.Map; 56import java.util.Properties; 57 58import 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. 65public 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 165 public FolderConfiguration getFolderConfig() { 166 FolderConfiguration config = new FolderConfiguration(); 167 config.createDefault(); 168 config.setDensityQualifier(new DensityQualifier(mDensity)); 169 config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation)); 170 if (mScreenWidth > mScreenHeight) { 171 config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth, 172 mScreenHeight)); 173 } else { 174 config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight, 175 mScreenWidth)); 176 } 177 config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio)); 178 config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize)); 179 config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard)); 180 config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen)); 181 config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState)); 182 config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation)); 183 184 config.updateScreenWidthAndHeight(); 185 186 // some default qualifiers. 187 config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL)); 188 config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT)); 189 config.setCountryCodeQualifier(new CountryCodeQualifier()); 190 config.setLayoutDirectionQualifier(new LayoutDirectionQualifier()); 191 config.setNetworkCodeQualifier(new NetworkCodeQualifier()); 192 config.setLocaleQualifier(new LocaleQualifier()); 193 config.setVersionQualifier(new VersionQualifier()); 194 return config; 195 } 196 197 public HardwareConfig getHardwareConfig() { 198 return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize, 199 mOrientation, null, mSoftButtons); 200 } 201 202 public static Map<String, String> loadProperties(File path) { 203 Properties p = new Properties(); 204 Map<String, String> map = Maps.newHashMap(); 205 try { 206 p.load(new FileInputStream(path)); 207 for (String key : p.stringPropertyNames()) { 208 map.put(key, p.getProperty(key)); 209 } 210 } catch (IOException e) { 211 e.printStackTrace(); 212 } 213 return map; 214 } 215 216 public static Map<String, Map<String, Integer>> getEnumMap(File path) { 217 Map<String, Map<String, Integer>> map = Maps.newHashMap(); 218 try { 219 XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); 220 xmlPullParser.setInput(new FileInputStream(path), null); 221 int eventType = xmlPullParser.getEventType(); 222 String attr = null; 223 while (eventType != XmlPullParser.END_DOCUMENT) { 224 if (eventType == XmlPullParser.START_TAG) { 225 if (TAG_ATTR.equals(xmlPullParser.getName())) { 226 attr = xmlPullParser.getAttributeValue(null, ATTR_NAME); 227 } else if (TAG_ENUM.equals(xmlPullParser.getName()) 228 || TAG_FLAG.equals(xmlPullParser.getName())) { 229 String name = xmlPullParser.getAttributeValue(null, ATTR_NAME); 230 String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE); 231 // Integer.decode cannot handle "ffffffff", see JDK issue 6624867 232 int i = (int) (long) Long.decode(value); 233 assert attr != null; 234 Map<String, Integer> attributeMap = map.get(attr); 235 if (attributeMap == null) { 236 attributeMap = Maps.newHashMap(); 237 map.put(attr, attributeMap); 238 } 239 attributeMap.put(name, i); 240 } 241 } else if (eventType == XmlPullParser.END_TAG) { 242 if (TAG_ATTR.equals(xmlPullParser.getName())) { 243 attr = null; 244 } 245 } 246 eventType = xmlPullParser.next(); 247 } 248 } catch (XmlPullParserException e) { 249 e.printStackTrace(); 250 } catch (IOException e) { 251 e.printStackTrace(); 252 } 253 return map; 254 } 255 256 // Methods to set the configuration values. 257 258 public ConfigGenerator setScreenHeight(int height) { 259 mScreenHeight = height; 260 return this; 261 } 262 263 public ConfigGenerator setScreenWidth(int width) { 264 mScreenWidth = width; 265 return this; 266 } 267 268 public ConfigGenerator setXdpi(int xdpi) { 269 mXdpi = xdpi; 270 return this; 271 } 272 273 public ConfigGenerator setYdpi(int ydpi) { 274 mYdpi = ydpi; 275 return this; 276 } 277 278 public ConfigGenerator setOrientation(ScreenOrientation orientation) { 279 mOrientation = orientation; 280 return this; 281 } 282 283 public ConfigGenerator setDensity(Density density) { 284 mDensity = density; 285 return this; 286 } 287 288 public ConfigGenerator setRatio(ScreenRatio ratio) { 289 mRatio = ratio; 290 return this; 291 } 292 293 public ConfigGenerator setSize(ScreenSize size) { 294 mSize = size; 295 return this; 296 } 297 298 public ConfigGenerator setKeyboard(Keyboard keyboard) { 299 mKeyboard = keyboard; 300 return this; 301 } 302 303 public ConfigGenerator setTouchScreen(TouchScreen touchScreen) { 304 mTouchScreen = touchScreen; 305 return this; 306 } 307 308 public ConfigGenerator setKeyboardState(KeyboardState state) { 309 mKeyboardState = state; 310 return this; 311 } 312 313 public ConfigGenerator setSoftButtons(boolean softButtons) { 314 mSoftButtons = softButtons; 315 return this; 316 } 317 318 public ConfigGenerator setNavigation(Navigation navigation) { 319 mNavigation = navigation; 320 return this; 321 } 322} 323