am c124b2ab: Merge change Ib1b01007 into eclair

Merge commit 'c124b2ab7bb228a3363535c6697708a82016ce70' into eclair-plus-aosp

* commit 'c124b2ab7bb228a3363535c6697708a82016ce70':
  Parse add-on supplied layout devices.
This commit is contained in:
Xavier Ducrohet
2009-09-28 13:40:02 -07:00
committed by Android Git Automerger
20 changed files with 496 additions and 155 deletions

View File

@@ -1026,10 +1026,16 @@ public class AdtPlugin extends AbstractUIPlugin {
progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
int n = sdk.getTargets().length;
final IAndroidTarget[] targets = sdk.getTargets();
final int n = targets.length;
if (n > 0) {
// load the layout devices.
sdk.parseAddOnLayoutDevices();
// load the rest of the targes.
// TODO: make this on-demand.
int w = 60 / n;
for (IAndroidTarget target : sdk.getTargets()) {
for (IAndroidTarget target : targets) {
SubMonitor p2 = progress.newChild(w);
IStatus status = new AndroidTargetParser(target).run(p2);
if (status.getCode() != IStatus.OK) {

View File

@@ -975,6 +975,7 @@ public class GraphicalEditorPart extends EditorPart implements IGraphicalLayoutE
AndroidTargetData data = currentSdk.getTargetData(target);
if (data != null) {
LayoutBridge bridge = data.getLayoutBridge();
mConfigComposite.reloadDevices();
mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);
}
}

View File

@@ -738,6 +738,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
AndroidTargetData data = currentSdk.getTargetData(target);
if (data != null) {
LayoutBridge bridge = data.getLayoutBridge();
mConfigComposite.reloadDevices();
mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);
}
}

View File

@@ -28,6 +28,7 @@ import com.android.ide.eclipse.adt.internal.resources.configurations.VersionQual
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.sdk.DeviceConfiguration;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
@@ -46,6 +47,7 @@ import org.eclipse.swt.widgets.Label;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -73,7 +75,7 @@ public class ConfigurationComposite extends Composite {
/** The {@link FolderConfiguration} representing the state of the UI controls */
private final FolderConfiguration mCurrentConfig = new FolderConfiguration();
private DeviceConfiguration[] mDevices;
private List<DeviceConfiguration> mDevices;
private final ArrayList<ResourceQualifier[] > mLocaleList =
new ArrayList<ResourceQualifier[]>();
@@ -103,7 +105,9 @@ public class ConfigurationComposite extends Composite {
public ConfigurationComposite(IConfigListener listener, Composite parent, int style) {
super(parent, style);
mListener = listener;
mDevices = DeviceConfiguration.getDevices();
if (Sdk.getCurrent() != null) {
mDevices = Sdk.getCurrent().getLayoutDevices();
}
GridLayout gl;
GridData gd;
@@ -141,12 +145,6 @@ public class ConfigurationComposite extends Composite {
new Label(this, SWT.NONE).setText("Devices");
mDeviceList = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
// fill with the devices
for (DeviceConfiguration device : mDevices) {
mDeviceList.add(device.getName());
}
mDeviceList.select(0);
mDeviceList.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
mDeviceList.addSelectionListener(new SelectionAdapter() {
@@ -158,15 +156,6 @@ public class ConfigurationComposite extends Composite {
new Label(this, SWT.NONE).setText("Config");
mDeviceConfigs = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
Map<String, FolderConfiguration> configs = mDevices[0].getConfigs();
Set<String> configNames = configs.keySet();
for (String name : configNames) {
mDeviceConfigs.add(name);
}
mDeviceConfigs.select(0);
if (configNames.size() == 1) {
mDeviceConfigs.setEnabled(false);
}
mDeviceConfigs.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
mDeviceConfigs.addSelectionListener(new SelectionAdapter() {
@@ -224,9 +213,12 @@ public class ConfigurationComposite extends Composite {
}
});
initUiWithDevices();
onDeviceConfigChange();
}
public FolderConfiguration getCurrentConfig() {
return mCurrentConfig;
}
@@ -457,6 +449,44 @@ public class ConfigurationComposite extends Composite {
mDisableUpdates = false;
}
/**
* Reloads the list of {@link DeviceConfiguration} from the {@link Sdk}.
*/
public void reloadDevices() {
mDevices = Sdk.getCurrent().getLayoutDevices();
initUiWithDevices();
onDeviceChange();
}
/**
* Init the UI with the list of Devices.
*/
private void initUiWithDevices() {
// remove older devices if applicable
mDeviceList.removeAll();
mDeviceConfigs.removeAll();
// fill with the devices
if (mDevices != null) {
for (DeviceConfiguration device : mDevices) {
mDeviceList.add(device.getName());
}
mDeviceList.select(0);
if (mDevices.size() > 0) {
Map<String, FolderConfiguration> configs = mDevices.get(0).getConfigs();
Set<String> configNames = configs.keySet();
for (String name : configNames) {
mDeviceConfigs.add(name);
}
mDeviceConfigs.select(0);
if (configNames.size() == 1) {
mDeviceConfigs.setEnabled(false);
}
}
}
}
/**
* Call back for language combo selection
*/
@@ -481,7 +511,7 @@ public class ConfigurationComposite extends Composite {
private void onDeviceChange() {
int deviceIndex = mDeviceList.getSelectionIndex();
DeviceConfiguration device = mDevices[deviceIndex];
DeviceConfiguration device = mDevices.get(deviceIndex);
mDeviceConfigs.removeAll();
@@ -499,28 +529,30 @@ public class ConfigurationComposite extends Composite {
}
private void onDeviceConfigChange() {
int deviceIndex = mDeviceList.getSelectionIndex();
DeviceConfiguration device = mDevices[deviceIndex];
if (mDevices != null) {
int deviceIndex = mDeviceList.getSelectionIndex();
DeviceConfiguration device = mDevices.get(deviceIndex);
int configIndex = mDeviceConfigs.getSelectionIndex();
String name = mDeviceConfigs.getItem(configIndex);
FolderConfiguration config = device.getConfigs().get(name);
int configIndex = mDeviceConfigs.getSelectionIndex();
String name = mDeviceConfigs.getItem(configIndex);
FolderConfiguration config = device.getConfigs().get(name);
// get the current qualifiers from the current config
LanguageQualifier lang = mCurrentConfig.getLanguageQualifier();
RegionQualifier region = mCurrentConfig.getRegionQualifier();
VersionQualifier version = mCurrentConfig.getVersionQualifier();
// get the current qualifiers from the current config
LanguageQualifier lang = mCurrentConfig.getLanguageQualifier();
RegionQualifier region = mCurrentConfig.getRegionQualifier();
VersionQualifier version = mCurrentConfig.getVersionQualifier();
// replace the config with the one from the device
mCurrentConfig.set(config);
// replace the config with the one from the device
mCurrentConfig.set(config);
// and put back the rest of the qualifiers
mCurrentConfig.addQualifier(lang);
mCurrentConfig.addQualifier(region);
mCurrentConfig.addQualifier(version);
// and put back the rest of the qualifiers
mCurrentConfig.addQualifier(lang);
mCurrentConfig.addQualifier(region);
mCurrentConfig.addQualifier(version);
if (mListener != null) {
mListener.onConfigurationChange();
if (mListener != null) {
mListener.onConfigurationChange();
}
}
}
@@ -603,3 +635,4 @@ public class ConfigurationComposite extends Composite {
return false;
}
}

View File

@@ -53,7 +53,7 @@ public final class KeyboardStateQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static KeyboardState getEnum(String value) {
public static KeyboardState getEnum(String value) {
for (KeyboardState orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -54,7 +54,7 @@ public final class NavigationMethodQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static NavigationMethod getEnum(String value) {
public static NavigationMethod getEnum(String value) {
for (NavigationMethod orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -61,7 +61,7 @@ public final class PixelDensityQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static Density getEnum(String value) {
public static Density getEnum(String value) {
for (Density orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -51,7 +51,7 @@ public final class ScreenOrientationQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static ScreenOrientation getEnum(String value) {
public static ScreenOrientation getEnum(String value) {
for (ScreenOrientation orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -48,7 +48,7 @@ public class ScreenRatioQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static ScreenRatio getEnum(String value) {
public static ScreenRatio getEnum(String value) {
for (ScreenRatio orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -52,7 +52,7 @@ public class ScreenSizeQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static ScreenSize getEnum(String value) {
public static ScreenSize getEnum(String value) {
for (ScreenSize orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -54,7 +54,7 @@ public final class TextInputMethodQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static TextInputMethod getEnum(String value) {
public static TextInputMethod getEnum(String value) {
for (TextInputMethod orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -52,7 +52,7 @@ public final class TouchScreenQualifier extends ResourceQualifier {
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
static TouchScreenType getEnum(String value) {
public static TouchScreenType getEnum(String value) {
for (TouchScreenType orient : values()) {
if (orient.mValue.equals(value)) {
return orient;

View File

@@ -17,23 +17,6 @@
package com.android.ide.eclipse.adt.internal.sdk;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import java.util.Collections;
import java.util.HashMap;
@@ -64,66 +47,4 @@ public class DeviceConfiguration {
public Map<String, FolderConfiguration> getConfigs() {
return mMap;
}
/**
* temp method returning some hard-coded devices.
* TODO: load devices from the SDK and add-ons and remove this method.
*/
public static DeviceConfiguration[] getDevices() {
DeviceConfiguration adp1 = new DeviceConfiguration("ADP1");
// default config
FolderConfiguration defConfig = new FolderConfiguration();
defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
// specific configs
FolderConfiguration closedLand = new FolderConfiguration();
closedLand.set(defConfig);
closedLand.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
closedLand.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
adp1.addConfig("Closed, landscape", closedLand);
FolderConfiguration closedPort = new FolderConfiguration();
closedPort.set(defConfig);
closedPort.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
closedPort.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
adp1.addConfig("Closed, portrait", closedPort);
FolderConfiguration opened = new FolderConfiguration();
opened.set(defConfig);
opened.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
opened.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
adp1.addConfig("Opened", opened);
DeviceConfiguration ion = new DeviceConfiguration("Ion");
// default config
defConfig = new FolderConfiguration();
defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.NOKEY));
defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
// specific configs
FolderConfiguration landscape = new FolderConfiguration();
landscape.set(defConfig);
landscape.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
ion.addConfig("Landscape", landscape);
FolderConfiguration portrait = new FolderConfiguration();
portrait.set(defConfig);
portrait.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
ion.addConfig("Portrait", portrait);
return new DeviceConfiguration[] { adp1, ion };
}
}
}

View File

@@ -17,10 +17,19 @@
package com.android.ide.eclipse.adt.internal.sdk;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import java.io.InputStream;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
/**
* Public constants for the sdk-repository XML Schema.
* Public constants for the layout device description XML Schema.
*/
public class LayoutConfigsXsd {
@@ -100,4 +109,17 @@ public class LayoutConfigsXsd {
return LayoutConfigsXsd.class.getResourceAsStream("layout-configs.xsd"); //$NON-NLS-1$
}
/** Helper method that returns a {@link Validator} for our XSD */
public static Validator getValidator(ErrorHandler handler) throws SAXException {
InputStream xsdStream = getXsdStream();
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(xsdStream));
Validator validator = schema.newValidator();
if (handler != null) {
validator.setErrorHandler(handler);
}
return validator;
}
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.internal.sdk;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
/**
* {@link DefaultHandler} implementation to parse Layout Device XML file.
* @see LayoutConfigsXsd
* @see Layout-configs.xsd
*/
class LayoutDeviceHandler extends DefaultHandler {
/*
* The handler does most of the work in startElement and endElement.
* In startElement, it'll create DeviceConfiguration on <device>, as well as
* FolderConfiguration instances on <default> and <config>.
* Those objects are then filled as new nodes are discovered.
*
* For the qualifier values, the qualifier is created and added to the current config
* on the endElement, by using the content found in characters().
*/
private List<DeviceConfiguration> mDevices = new ArrayList<DeviceConfiguration>();
private DeviceConfiguration mCurrentDevice;
private FolderConfiguration mDefaultConfig;
private FolderConfiguration mCurrentConfig;
private final StringBuilder mStringAccumulator = new StringBuilder();
private String mSize1, mSize2;
public List<DeviceConfiguration> getDevices() {
return mDevices;
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) {
// get the deviceName, will not be null since we validated the XML.
String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME);
// create a device and add it to the list
mCurrentDevice = new DeviceConfiguration(deviceName);
mDevices.add(mCurrentDevice);
} else if (LayoutConfigsXsd.NODE_DEFAULT.equals(localName)) {
// create a new default config
mDefaultConfig = mCurrentConfig = new FolderConfiguration();
} else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) {
// create a new config
mCurrentConfig = new FolderConfiguration();
// init with default config if applicable
if (mDefaultConfig != null) {
mCurrentConfig.set(mDefaultConfig);
}
// get the name of the config
String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME);
// give it to the current device.
mCurrentDevice.addConfig(deviceName, mCurrentConfig);
} else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
mSize1 = mSize2 = null;
}
mStringAccumulator.setLength(0);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
mStringAccumulator.append(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) {
mCurrentDevice = null;
mDefaultConfig = null;
} else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) {
mCurrentConfig = null;
} else if (LayoutConfigsXsd.NODE_SCREEN_SIZE.equals(localName)) {
ScreenSizeQualifier ssq = new ScreenSizeQualifier(
ScreenSize.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setScreenSizeQualifier(ssq);
} else if (LayoutConfigsXsd.NODE_SCREEN_RATIO.equals(localName)) {
ScreenRatioQualifier srq = new ScreenRatioQualifier(
ScreenRatio.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setScreenRatioQualifier(srq);
} else if (LayoutConfigsXsd.NODE_SCREEN_ORIENTATION.equals(localName)) {
ScreenOrientationQualifier soq = new ScreenOrientationQualifier(
ScreenOrientation.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setScreenOrientationQualifier(soq);
} else if (LayoutConfigsXsd.NODE_PIXEL_DENSITY.equals(localName)) {
PixelDensityQualifier pdq = new PixelDensityQualifier(
Density.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setPixelDensityQualifier(pdq);
} else if (LayoutConfigsXsd.NODE_TOUCH_TYPE.equals(localName)) {
TouchScreenQualifier tsq = new TouchScreenQualifier(
TouchScreenType.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setTouchTypeQualifier(tsq);
} else if (LayoutConfigsXsd.NODE_KEYBOARD_STATE.equals(localName)) {
KeyboardStateQualifier ksq = new KeyboardStateQualifier(
KeyboardState.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setKeyboardStateQualifier(ksq);
} else if (LayoutConfigsXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) {
TextInputMethodQualifier timq = new TextInputMethodQualifier(
TextInputMethod.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setTextInputMethodQualifier(timq);
} else if (LayoutConfigsXsd.NODE_NAV_METHOD.equals(localName)) {
NavigationMethodQualifier nmq = new NavigationMethodQualifier(
NavigationMethod.getEnum(mStringAccumulator.toString()));
mCurrentConfig.setNavigationMethodQualifier(nmq);
} else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2);
if (qual != null) {
mCurrentConfig.setScreenDimensionQualifier(qual);
}
} else if (LayoutConfigsXsd.NODE_SIZE.equals(localName)) {
if (mSize1 == null) {
mSize1 = mStringAccumulator.toString();
} else if (mSize2 == null) {
mSize2 = mStringAccumulator.toString();
}
}
}
}

View File

@@ -19,6 +19,24 @@ package com.android.ide.eclipse.adt.internal.sdk;
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
@@ -41,15 +59,31 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Validator;
/**
* Central point to load, manipulate and deal with the Android SDK. Only one SDK can be used
* at the same time.
@@ -73,6 +107,8 @@ public class Sdk implements IProjectListener {
new HashMap<IProject, ApkSettings>();
private final String mDocBaseUrl;
private List<DeviceConfiguration> mLayoutDevices = new ArrayList<DeviceConfiguration>();
/**
* Classes implementing this interface will receive notification when targets are changed.
*/
@@ -432,6 +468,9 @@ public class Sdk implements IProjectListener {
// pre-compute some paths
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
SdkConstants.OS_SDK_DOCS_FOLDER);
// create some built-in layout devices
createDefaultLayoutDevices();
}
/**
@@ -518,6 +557,173 @@ public class Sdk implements IProjectListener {
// ignore this. The project will be added to the map the first time the target needs
// to be resolved.
}
// ---------- Device Configuration methods ----------
/**
* A SAX error handler that captures the errors and warnings.
* This allows us to capture *all* errors and just not get an exception on the first one.
*/
private static class CaptureErrorHandler implements ErrorHandler {
private final String mSourceLocation;
private boolean mFoundError = false;
CaptureErrorHandler(String sourceLocation) {
mSourceLocation = sourceLocation;
}
public boolean foundError() {
return mFoundError;
}
/**
* @throws SAXException
*/
public void error(SAXParseException ex) throws SAXException {
mFoundError = true;
AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
}
/**
* @throws SAXException
*/
public void fatalError(SAXParseException ex) throws SAXException {
mFoundError = true;
AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
}
/**
* @throws SAXException
*/
public void warning(SAXParseException ex) throws SAXException {
// ignore those for now.
}
}
/**
* Returns the list of {@link DeviceConfiguration} found in the SDK.
*/
public List<DeviceConfiguration> getLayoutDevices() {
return mLayoutDevices;
}
/**
* Parses the SDK add-ons to look for files called {@link SdkConstants#FN_DEVICES_XML} to
* load {@link DeviceConfiguration} from them.
*/
public void parseAddOnLayoutDevices() {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
IAndroidTarget[] targets = mManager.getTargets();
for (IAndroidTarget target : targets) {
if (target.isPlatform() == false) {
File deviceXml = new File(target.getLocation(), SdkConstants.FN_DEVICES_XML);
if (deviceXml.isFile()) {
parseLayoutDevices(parserFactory, deviceXml);
}
}
}
mLayoutDevices = Collections.unmodifiableList(mLayoutDevices);
}
/**
* Does the actual parsing of a devices.xml file.
*/
private void parseLayoutDevices(SAXParserFactory parserFactory, File deviceXml) {
// first we validate the XML
try {
Source source = new StreamSource(new FileReader(deviceXml));
CaptureErrorHandler errorHandler = new CaptureErrorHandler(deviceXml.getAbsolutePath());
Validator validator = LayoutConfigsXsd.getValidator(errorHandler);
validator.validate(source);
if (errorHandler.foundError() == false) {
// do the actual parsing
LayoutDeviceHandler handler = new LayoutDeviceHandler();
SAXParser parser = parserFactory.newSAXParser();
parser.parse(new InputSource(new FileInputStream(deviceXml)), handler);
// get the parsed devices
mLayoutDevices.addAll(handler.getDevices());
}
} catch (SAXException e) {
AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
} catch (FileNotFoundException e) {
// this shouldn't happen as we check above.
} catch (IOException e) {
AdtPlugin.log(e, "Error reading %1$s", deviceXml.getAbsoluteFile());
} catch (ParserConfigurationException e) {
AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
}
}
/**
* Creates some built-it layout devices.
*/
private void createDefaultLayoutDevices() {
DeviceConfiguration adp1 = new DeviceConfiguration("ADP1");
mLayoutDevices.add(adp1);
// default config
FolderConfiguration defConfig = new FolderConfiguration();
defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.SOFT));
defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
// specific configs
FolderConfiguration closedPort = new FolderConfiguration();
closedPort.set(defConfig);
closedPort.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
adp1.addConfig("Portrait, closed", closedPort);
FolderConfiguration closedLand = new FolderConfiguration();
closedLand.set(defConfig);
closedLand.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
adp1.addConfig("Landscape, closed", closedLand);
FolderConfiguration opened = new FolderConfiguration();
opened.set(defConfig);
opened.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
opened.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
adp1.addConfig("Landscape, opened", opened);
DeviceConfiguration ion = new DeviceConfiguration("Ion");
mLayoutDevices.add(ion);
// default config
defConfig = new FolderConfiguration();
defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.NOKEY));
defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
// specific configs
FolderConfiguration landscape = new FolderConfiguration();
landscape.set(defConfig);
landscape.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
ion.addConfig("Landscape", landscape);
FolderConfiguration portrait = new FolderConfiguration();
portrait.set(defConfig);
portrait.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
ion.addConfig("Portrait", portrait);
}
}

View File

@@ -92,7 +92,7 @@
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="small" />
<xsd:enumeration value="medium" />
<xsd:enumeration value="normal" />
<xsd:enumeration value="large" />
</xsd:restriction>
</xsd:simpleType>

View File

@@ -23,11 +23,8 @@ import org.xml.sax.SAXParseException;
import java.io.InputStream;
import java.io.StringReader;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import junit.framework.TestCase;
@@ -107,19 +104,6 @@ public class TestLayoutConfisXsd extends TestCase {
// --- Helpers ------------
/** Helper method that returns a validator for our XSD */
private Validator getValidator(CaptureErrorHandler handler) throws SAXException {
InputStream xsdStream = LayoutConfigsXsd.getXsdStream();
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(xsdStream));
Validator validator = schema.newValidator();
if (handler != null) {
validator.setErrorHandler(handler);
}
return validator;
}
/** Validate a valid sample using an InputStream */
public void testValidateLocalRepositoryFile() throws Exception {
@@ -128,7 +112,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(xmlStream);
CaptureErrorHandler handler = new CaptureErrorHandler();
Validator validator = getValidator(handler);
Validator validator = LayoutConfigsXsd.getValidator(handler);
validator.validate(source);
handler.verify();
}
@@ -151,7 +135,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
CaptureErrorHandler handler = new CaptureErrorHandler();
Validator validator = getValidator(handler);
Validator validator = LayoutConfigsXsd.getValidator(handler);
try {
validator.validate(source);
@@ -175,7 +159,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -197,7 +181,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -217,7 +201,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -239,7 +223,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -264,7 +248,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {
@@ -289,7 +273,7 @@ public class TestLayoutConfisXsd extends TestCase {
Source source = new StreamSource(new StringReader(document));
// don't capture the validator errors, we want it to fail and catch the exception
Validator validator = getValidator(null);
Validator validator = LayoutConfigsXsd.getValidator(null);
try {
validator.validate(source);
} catch (SAXParseException e) {

View File

@@ -50,8 +50,8 @@
<d:config name="screen-size-small">
<d:screen-size>small</d:screen-size>
</d:config>
<d:config name="screen-size-medium">
<d:screen-size>medium</d:screen-size>
<d:config name="screen-size-normal">
<d:screen-size>normal</d:screen-size>
</d:config>
<d:config name="screen-size-large">
<d:screen-size>large</d:screen-size>
@@ -121,8 +121,8 @@
<d:device name="SomePhone"> <!-- 1..n -->
<d:config name="screen-size-medium">
<d:screen-size>medium</d:screen-size>
<d:config name="screen-size-normal">
<d:screen-size>normal</d:screen-size>
</d:config>
</d:device>

View File

@@ -78,6 +78,8 @@ public final class SdkConstants {
public final static String FN_PLUGIN_PROP = "plugin.prop";
/** add-on manifest file */
public final static String FN_MANIFEST_INI = "manifest.ini";
/** add-on layout device XML file. */
public final static String FN_DEVICES_XML = "devices.xml";
/** hardware properties definition file */
public final static String FN_HARDWARE_INI = "hardware-properties.ini";