aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java843
1 files changed, 0 insertions, 843 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java
deleted file mode 100644
index 9724d4015..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/ConfigurationMatcher.java
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * Copyright (C) 2012 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.editors.layout.configuration;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.resources.ResourceFile;
-import com.android.ide.common.resources.configuration.DensityQualifier;
-import com.android.ide.common.resources.configuration.DeviceConfigHelper;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.LocaleQualifier;
-import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.ResourceQualifier;
-import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
-import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
-import com.android.ide.common.resources.configuration.UiModeQualifier;
-import com.android.ide.common.resources.configuration.VersionQualifier;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.io.IFileWrapper;
-import com.android.resources.Density;
-import com.android.resources.NightMode;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenSize;
-import com.android.resources.UiMode;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.devices.Device;
-import com.android.sdklib.devices.State;
-import com.android.sdklib.repository.PkgProps;
-import com.android.utils.Pair;
-import com.android.utils.SparseIntArray;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.ui.IEditorPart;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Produces matches for configurations
- * <p>
- * See algorithm described here:
- * http://developer.android.com/guide/topics/resources/providing-resources.html
- */
-public class ConfigurationMatcher {
- private static final boolean PREFER_RECENT_RENDER_TARGETS = true;
-
- private final ConfigurationChooser mConfigChooser;
- private final Configuration mConfiguration;
- private final IFile mEditedFile;
- private final ProjectResources mResources;
- private final boolean mUpdateUi;
-
- ConfigurationMatcher(ConfigurationChooser chooser) {
- this(chooser, chooser.getConfiguration(), chooser.getEditedFile(),
- chooser.getResources(), true);
- }
-
- ConfigurationMatcher(
- @NonNull ConfigurationChooser chooser,
- @NonNull Configuration configuration,
- @Nullable IFile editedFile,
- @Nullable ProjectResources resources,
- boolean updateUi) {
- mConfigChooser = chooser;
- mConfiguration = configuration;
- mEditedFile = editedFile;
- mResources = resources;
- mUpdateUi = updateUi;
- }
-
- // ---- Finding matching configurations ----
-
- private static class ConfigBundle {
- private final FolderConfiguration config;
- private int localeIndex;
- private int dockModeIndex;
- private int nightModeIndex;
-
- private ConfigBundle() {
- config = new FolderConfiguration();
- }
-
- private ConfigBundle(ConfigBundle bundle) {
- config = new FolderConfiguration();
- config.set(bundle.config);
- localeIndex = bundle.localeIndex;
- dockModeIndex = bundle.dockModeIndex;
- nightModeIndex = bundle.nightModeIndex;
- }
- }
-
- private static class ConfigMatch {
- final FolderConfiguration testConfig;
- final Device device;
- final State state;
- final ConfigBundle bundle;
-
- public ConfigMatch(@NonNull FolderConfiguration testConfig, @NonNull Device device,
- @NonNull State state, @NonNull ConfigBundle bundle) {
- this.testConfig = testConfig;
- this.device = device;
- this.state = state;
- this.bundle = bundle;
- }
-
- @Override
- public String toString() {
- return device.getName() + " - " + state.getName();
- }
- }
-
- /**
- * Checks whether the current edited file is the best match for a given config.
- * <p>
- * This tests against other versions of the same layout in the project.
- * <p>
- * The given config must be compatible with the current edited file.
- * @param config the config to test.
- * @return true if the current edited file is the best match in the project for the
- * given config.
- */
- public boolean isCurrentFileBestMatchFor(FolderConfiguration config) {
- ResourceFile match = mResources.getMatchingFile(mEditedFile.getName(),
- ResourceType.LAYOUT, config);
-
- if (match != null) {
- return match.getFile().equals(mEditedFile);
- } else {
- // if we stop here that means the current file is not even a match!
- AdtPlugin.log(IStatus.ERROR, "Current file is not a match for the given config.");
- }
-
- return false;
- }
-
- /**
- * Adapts the current device/config selection so that it's compatible with
- * the configuration.
- * <p>
- * If the current selection is compatible, nothing is changed.
- * <p>
- * If it's not compatible, configs from the current devices are tested.
- * <p>
- * If none are compatible, it reverts to
- * {@link #findAndSetCompatibleConfig(boolean)}
- */
- void adaptConfigSelection(boolean needBestMatch) {
- // check the device config (ie sans locale)
- boolean needConfigChange = true; // if still true, we need to find another config.
- boolean currentConfigIsCompatible = false;
- State selectedState = mConfiguration.getDeviceState();
- FolderConfiguration editedConfig = mConfiguration.getEditedConfig();
- if (selectedState != null) {
- FolderConfiguration currentConfig = DeviceConfigHelper.getFolderConfig(selectedState);
- if (currentConfig != null && editedConfig.isMatchFor(currentConfig)) {
- currentConfigIsCompatible = true; // current config is compatible
- if (!needBestMatch || isCurrentFileBestMatchFor(currentConfig)) {
- needConfigChange = false;
- }
- }
- }
-
- if (needConfigChange) {
- List<Locale> localeList = mConfigChooser.getLocaleList();
-
- // if the current state/locale isn't a correct match, then
- // look for another state/locale in the same device.
- FolderConfiguration testConfig = new FolderConfiguration();
-
- // first look in the current device.
- State matchState = null;
- int localeIndex = -1;
- Device device = mConfiguration.getDevice();
- if (device != null) {
- mainloop: for (State state : device.getAllStates()) {
- testConfig.set(DeviceConfigHelper.getFolderConfig(state));
-
- // loop on the locales.
- for (int i = 0 ; i < localeList.size() ; i++) {
- Locale locale = localeList.get(i);
-
- // update the test config with the locale qualifiers
- testConfig.setLocaleQualifier(locale.qualifier);
-
-
- if (editedConfig.isMatchFor(testConfig) &&
- isCurrentFileBestMatchFor(testConfig)) {
- matchState = state;
- localeIndex = i;
- break mainloop;
- }
- }
- }
- }
-
- if (matchState != null) {
- mConfiguration.setDeviceState(matchState, true);
- Locale locale = localeList.get(localeIndex);
- mConfiguration.setLocale(locale, true);
- if (mUpdateUi) {
- mConfigChooser.selectDeviceState(matchState);
- mConfigChooser.selectLocale(locale);
- }
- mConfiguration.syncFolderConfig();
- } else {
- // no match in current device with any state/locale
- // attempt to find another device that can display this
- // particular state.
- findAndSetCompatibleConfig(currentConfigIsCompatible);
- }
- }
- }
-
- /**
- * Finds a device/config that can display a configuration.
- * <p>
- * Once found the device and config combos are set to the config.
- * <p>
- * If there is no compatible configuration, a custom one is created.
- *
- * @param favorCurrentConfig if true, and no best match is found, don't
- * change the current config. This must only be true if the
- * current config is compatible.
- */
- void findAndSetCompatibleConfig(boolean favorCurrentConfig) {
- List<Locale> localeList = mConfigChooser.getLocaleList();
- Collection<Device> devices = mConfigChooser.getDevices();
- FolderConfiguration editedConfig = mConfiguration.getEditedConfig();
- FolderConfiguration currentConfig = mConfiguration.getFullConfig();
-
- // list of compatible device/state/locale
- List<ConfigMatch> anyMatches = new ArrayList<ConfigMatch>();
-
- // list of actual best match (ie the file is a best match for the
- // device/state)
- List<ConfigMatch> bestMatches = new ArrayList<ConfigMatch>();
-
- // get a locale that match the host locale roughly (may not be exact match on the region.)
- int localeHostMatch = getLocaleMatch();
-
- // build a list of combinations of non standard qualifiers to add to each device's
- // qualifier set when testing for a match.
- // These qualifiers are: locale, night-mode, car dock.
- List<ConfigBundle> configBundles = new ArrayList<ConfigBundle>(200);
-
- // If the edited file has locales, then we have to select a matching locale from
- // the list.
- // However, if it doesn't, we don't randomly take the first locale, we take one
- // matching the current host locale (making sure it actually exist in the project)
- int start, max;
- if (editedConfig.getLocaleQualifier() != null || localeHostMatch == -1) {
- // add all the locales
- start = 0;
- max = localeList.size();
- } else {
- // only add the locale host match
- start = localeHostMatch;
- max = localeHostMatch + 1; // test is <
- }
-
- for (int i = start ; i < max ; i++) {
- Locale l = localeList.get(i);
-
- ConfigBundle bundle = new ConfigBundle();
- bundle.config.setLocaleQualifier(l.qualifier);
-
- bundle.localeIndex = i;
- configBundles.add(bundle);
- }
-
- // add the dock mode to the bundle combinations.
- addDockModeToBundles(configBundles);
-
- // add the night mode to the bundle combinations.
- addNightModeToBundles(configBundles);
-
- addRenderTargetToBundles(configBundles);
-
- for (Device device : devices) {
- for (State state : device.getAllStates()) {
-
- // loop on the list of config bundles to create full
- // configurations.
- FolderConfiguration stateConfig = DeviceConfigHelper.getFolderConfig(state);
- for (ConfigBundle bundle : configBundles) {
- // create a new config with device config
- FolderConfiguration testConfig = new FolderConfiguration();
- testConfig.set(stateConfig);
-
- // add on top of it, the extra qualifiers from the bundle
- testConfig.add(bundle.config);
-
- if (editedConfig.isMatchFor(testConfig)) {
- // this is a basic match. record it in case we don't
- // find a match
- // where the edited file is a best config.
- anyMatches.add(new ConfigMatch(testConfig, device, state, bundle));
-
- if (isCurrentFileBestMatchFor(testConfig)) {
- // this is what we want.
- bestMatches.add(new ConfigMatch(testConfig, device, state, bundle));
- }
- }
- }
- }
- }
-
- if (bestMatches.size() == 0) {
- if (favorCurrentConfig) {
- // quick check
- if (!editedConfig.isMatchFor(currentConfig)) {
- AdtPlugin.log(IStatus.ERROR,
- "favorCurrentConfig can only be true if the current config is compatible");
- }
-
- // just display the warning
- AdtPlugin.printErrorToConsole(mEditedFile.getProject(),
- String.format(
- "'%1$s' is not a best match for any device/locale combination.",
- editedConfig.toDisplayString()),
- String.format(
- "Displaying it with '%1$s'",
- currentConfig.toDisplayString()));
- } else if (anyMatches.size() > 0) {
- // select the best device anyway.
- ConfigMatch match = selectConfigMatch(anyMatches);
- mConfiguration.setDevice(match.device, true);
- mConfiguration.setDeviceState(match.state, true);
- mConfiguration.setLocale(localeList.get(match.bundle.localeIndex), true);
- mConfiguration.setUiMode(UiMode.getByIndex(match.bundle.dockModeIndex), true);
- mConfiguration.setNightMode(NightMode.getByIndex(match.bundle.nightModeIndex),
- true);
-
- if (mUpdateUi) {
- mConfigChooser.selectDevice(mConfiguration.getDevice());
- mConfigChooser.selectDeviceState(mConfiguration.getDeviceState());
- mConfigChooser.selectLocale(mConfiguration.getLocale());
- }
-
- mConfiguration.syncFolderConfig();
-
- // TODO: display a better warning!
- AdtPlugin.printErrorToConsole(mEditedFile.getProject(),
- String.format(
- "'%1$s' is not a best match for any device/locale combination.",
- editedConfig.toDisplayString()),
- String.format(
- "Displaying it with '%1$s' which is compatible, but will " +
- "actually be displayed with another more specific version of " +
- "the layout.",
- currentConfig.toDisplayString()));
-
- } else {
- // TODO: there is no device/config able to display the layout, create one.
- // For the base config values, we'll take the first device and state,
- // and replace whatever qualifier required by the layout file.
- }
- } else {
- ConfigMatch match = selectConfigMatch(bestMatches);
- mConfiguration.setDevice(match.device, true);
- mConfiguration.setDeviceState(match.state, true);
- mConfiguration.setLocale(localeList.get(match.bundle.localeIndex), true);
- mConfiguration.setUiMode(UiMode.getByIndex(match.bundle.dockModeIndex), true);
- mConfiguration.setNightMode(NightMode.getByIndex(match.bundle.nightModeIndex), true);
-
- mConfiguration.syncFolderConfig();
-
- if (mUpdateUi) {
- mConfigChooser.selectDevice(mConfiguration.getDevice());
- mConfigChooser.selectDeviceState(mConfiguration.getDeviceState());
- mConfigChooser.selectLocale(mConfiguration.getLocale());
- }
- }
- }
-
- private void addRenderTargetToBundles(List<ConfigBundle> configBundles) {
- Pair<Locale, IAndroidTarget> state = Configuration.loadRenderState(mConfigChooser);
- if (state != null) {
- IAndroidTarget target = state.getSecond();
- if (target != null) {
- int apiLevel = target.getVersion().getApiLevel();
- for (ConfigBundle bundle : configBundles) {
- bundle.config.setVersionQualifier(
- new VersionQualifier(apiLevel));
- }
- }
- }
- }
-
- private void addDockModeToBundles(List<ConfigBundle> addConfig) {
- ArrayList<ConfigBundle> list = new ArrayList<ConfigBundle>();
-
- // loop on each item and for each, add all variations of the dock modes
- for (ConfigBundle bundle : addConfig) {
- int index = 0;
- for (UiMode mode : UiMode.values()) {
- ConfigBundle b = new ConfigBundle(bundle);
- b.config.setUiModeQualifier(new UiModeQualifier(mode));
- b.dockModeIndex = index++;
- list.add(b);
- }
- }
-
- addConfig.clear();
- addConfig.addAll(list);
- }
-
- private void addNightModeToBundles(List<ConfigBundle> addConfig) {
- ArrayList<ConfigBundle> list = new ArrayList<ConfigBundle>();
-
- // loop on each item and for each, add all variations of the night modes
- for (ConfigBundle bundle : addConfig) {
- int index = 0;
- for (NightMode mode : NightMode.values()) {
- ConfigBundle b = new ConfigBundle(bundle);
- b.config.setNightModeQualifier(new NightModeQualifier(mode));
- b.nightModeIndex = index++;
- list.add(b);
- }
- }
-
- addConfig.clear();
- addConfig.addAll(list);
- }
-
- private int getLocaleMatch() {
- java.util.Locale defaultLocale = java.util.Locale.getDefault();
- if (defaultLocale != null) {
- String currentLanguage = defaultLocale.getLanguage();
- String currentRegion = defaultLocale.getCountry();
-
- List<Locale> localeList = mConfigChooser.getLocaleList();
- final int count = localeList.size();
- for (int l = 0; l < count; l++) {
- Locale locale = localeList.get(l);
- LocaleQualifier qualifier = locale.qualifier;
-
- // there's always a ##/Other or ##/Any (which is the same, the region
- // contains FAKE_REGION_VALUE). If we don't find a perfect region match
- // we take the fake region. Since it's last in the list, this makes the
- // test easy.
- if (qualifier.getLanguage().equals(currentLanguage) &&
- (qualifier.getRegion() == null || qualifier.getRegion().equals(currentRegion))) {
- return l;
- }
- }
-
- // if no locale match the current local locale, it's likely that it is
- // the default one which is the last one.
- return count - 1;
- }
-
- return -1;
- }
-
- private ConfigMatch selectConfigMatch(List<ConfigMatch> matches) {
- // API 11-13: look for a x-large device
- Comparator<ConfigMatch> comparator = null;
- Sdk sdk = Sdk.getCurrent();
- if (sdk != null) {
- IAndroidTarget projectTarget = sdk.getTarget(mEditedFile.getProject());
- if (projectTarget != null) {
- int apiLevel = projectTarget.getVersion().getApiLevel();
- if (apiLevel >= 11 && apiLevel < 14) {
- // TODO: Maybe check the compatible-screen tag in the manifest to figure out
- // what kind of device should be used for display.
- comparator = new TabletConfigComparator();
- }
- }
- }
- if (comparator == null) {
- // lets look for a high density device
- comparator = new PhoneConfigComparator();
- }
- Collections.sort(matches, comparator);
-
- // Look at the currently active editor to see if it's a layout editor, and if so,
- // look up its configuration and if the configuration is in our match list,
- // use it. This means we "preserve" the current configuration when you open
- // new layouts.
- IEditorPart activeEditor = AdtUtils.getActiveEditor();
- LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(activeEditor);
- if (delegate != null
- // (Only do this when the two files are in the same project)
- && delegate.getEditor().getProject() == mEditedFile.getProject()) {
- FolderConfiguration configuration = delegate.getGraphicalEditor().getConfiguration();
- if (configuration != null) {
- for (ConfigMatch match : matches) {
- if (configuration.equals(match.testConfig)) {
- return match;
- }
- }
- }
- }
-
- // the list has been sorted so that the first item is the best config
- return matches.get(0);
- }
-
- /** Return the default render target to use, or null if no strong preference */
- @Nullable
- static IAndroidTarget findDefaultRenderTarget(ConfigurationChooser chooser) {
- if (PREFER_RECENT_RENDER_TARGETS) {
- // Use the most recent target
- List<IAndroidTarget> targetList = chooser.getTargetList();
- if (!targetList.isEmpty()) {
- return targetList.get(targetList.size() - 1);
- }
- }
-
- IProject project = chooser.getProject();
- // Default to layoutlib version 5
- Sdk current = Sdk.getCurrent();
- if (current != null) {
- IAndroidTarget projectTarget = current.getTarget(project);
- int minProjectApi = Integer.MAX_VALUE;
- if (projectTarget != null) {
- if (!projectTarget.isPlatform() && projectTarget.hasRenderingLibrary()) {
- // Renderable non-platform targets are all going to be adequate (they
- // will have at least version 5 of layoutlib) so use the project
- // target as the render target.
- return projectTarget;
- }
-
- if (projectTarget.getVersion().isPreview()
- && projectTarget.hasRenderingLibrary()) {
- // If the project target is a preview version, then just use it
- return projectTarget;
- }
-
- minProjectApi = projectTarget.getVersion().getApiLevel();
- }
-
- // We want to pick a render target that contains at least version 5 (and
- // preferably version 6) of the layout library. To do this, we go through the
- // targets and pick the -smallest- API level that is both simultaneously at
- // least as big as the project API level, and supports layoutlib level 5+.
- IAndroidTarget best = null;
- int bestApiLevel = Integer.MAX_VALUE;
-
- for (IAndroidTarget target : current.getTargets()) {
- // Non-platform targets are not chosen as the default render target
- if (!target.isPlatform()) {
- continue;
- }
-
- int apiLevel = target.getVersion().getApiLevel();
-
- // Ignore targets that have a lower API level than the minimum project
- // API level:
- if (apiLevel < minProjectApi) {
- continue;
- }
-
- // Look up the layout lib API level. This property is new so it will only
- // be defined for version 6 or higher, which means non-null is adequate
- // to see if this target is eligible:
- String property = target.getProperty(PkgProps.LAYOUTLIB_API);
- // In addition, Android 3.0 with API level 11 had version 5.0 which is adequate:
- if (property != null || apiLevel >= 11) {
- if (apiLevel < bestApiLevel) {
- bestApiLevel = apiLevel;
- best = target;
- }
- }
- }
-
- return best;
- }
-
- return null;
- }
-
- /**
- * Attempts to find a close state among a list
- *
- * @param oldConfig the reference config.
- * @param states the list of states to search through
- * @return the name of the closest state match, or possibly null if no states are compatible
- * (this can only happen if the states don't have a single qualifier that is the same).
- */
- @Nullable
- static String getClosestMatch(@NonNull FolderConfiguration oldConfig,
- @NonNull List<State> states) {
-
- // create 2 lists as we're going to go through one and put the
- // candidates in the other.
- List<State> list1 = new ArrayList<State>(states.size());
- List<State> list2 = new ArrayList<State>(states.size());
-
- list1.addAll(states);
-
- final int count = FolderConfiguration.getQualifierCount();
- for (int i = 0 ; i < count ; i++) {
- // compute the new candidate list by only taking states that have
- // the same i-th qualifier as the old state
- for (State s : list1) {
- ResourceQualifier oldQualifier = oldConfig.getQualifier(i);
-
- FolderConfiguration folderConfig = DeviceConfigHelper.getFolderConfig(s);
- ResourceQualifier newQualifier =
- folderConfig != null ? folderConfig.getQualifier(i) : null;
-
- if (oldQualifier == null) {
- if (newQualifier == null) {
- list2.add(s);
- }
- } else if (oldQualifier.equals(newQualifier)) {
- list2.add(s);
- }
- }
-
- // at any moment if the new candidate list contains only one match, its name
- // is returned.
- if (list2.size() == 1) {
- return list2.get(0).getName();
- }
-
- // if the list is empty, then all the new states failed. It is considered ok, and
- // we move to the next qualifier anyway. This way, if a qualifier is different for
- // all new states it is simply ignored.
- if (list2.size() != 0) {
- // move the candidates back into list1.
- list1.clear();
- list1.addAll(list2);
- list2.clear();
- }
- }
-
- // the only way to reach this point is if there's an exact match.
- // (if there are more than one, then there's a duplicate state and it doesn't matter,
- // we take the first one).
- if (list1.size() > 0) {
- return list1.get(0).getName();
- }
-
- return null;
- }
-
- /**
- * Returns the layout {@link IFile} which best matches the configuration
- * selected in the given configuration chooser.
- *
- * @param chooser the associated configuration chooser holding project state
- * @return the file which best matches the settings
- */
- @Nullable
- public static IFile getBestFileMatch(ConfigurationChooser chooser) {
- // get the resources of the file's project.
- ResourceManager manager = ResourceManager.getInstance();
- ProjectResources resources = manager.getProjectResources(chooser.getProject());
- if (resources == null) {
- return null;
- }
-
- // From the resources, look for a matching file
- IFile editedFile = chooser.getEditedFile();
- if (editedFile == null) {
- return null;
- }
- String name = editedFile.getName();
- FolderConfiguration config = chooser.getConfiguration().getFullConfig();
- ResourceFile match = resources.getMatchingFile(name, ResourceType.LAYOUT, config);
-
- if (match != null) {
- // In Eclipse, the match's file is always an instance of IFileWrapper
- return ((IFileWrapper) match.getFile()).getIFile();
- }
-
- return null;
- }
-
- /**
- * Note: this comparator imposes orderings that are inconsistent with equals.
- */
- private static class TabletConfigComparator implements Comparator<ConfigMatch> {
- @Override
- public int compare(ConfigMatch o1, ConfigMatch o2) {
- FolderConfiguration config1 = o1 != null ? o1.testConfig : null;
- FolderConfiguration config2 = o2 != null ? o2.testConfig : null;
- if (config1 == null) {
- if (config2 == null) {
- return 0;
- } else {
- return -1;
- }
- } else if (config2 == null) {
- return 1;
- }
-
- ScreenSizeQualifier size1 = config1.getScreenSizeQualifier();
- ScreenSizeQualifier size2 = config2.getScreenSizeQualifier();
- ScreenSize ss1 = size1 != null ? size1.getValue() : ScreenSize.NORMAL;
- ScreenSize ss2 = size2 != null ? size2.getValue() : ScreenSize.NORMAL;
-
- // X-LARGE is better than all others (which are considered identical)
- // if both X-LARGE, then LANDSCAPE is better than all others (which are identical)
-
- if (ss1 == ScreenSize.XLARGE) {
- if (ss2 == ScreenSize.XLARGE) {
- ScreenOrientationQualifier orientation1 =
- config1.getScreenOrientationQualifier();
- ScreenOrientation so1 = orientation1.getValue();
- if (so1 == null) {
- so1 = ScreenOrientation.PORTRAIT;
- }
- ScreenOrientationQualifier orientation2 =
- config2.getScreenOrientationQualifier();
- ScreenOrientation so2 = orientation2.getValue();
- if (so2 == null) {
- so2 = ScreenOrientation.PORTRAIT;
- }
-
- if (so1 == ScreenOrientation.LANDSCAPE) {
- if (so2 == ScreenOrientation.LANDSCAPE) {
- return 0;
- } else {
- return -1;
- }
- } else if (so2 == ScreenOrientation.LANDSCAPE) {
- return 1;
- } else {
- return 0;
- }
- } else {
- return -1;
- }
- } else if (ss2 == ScreenSize.XLARGE) {
- return 1;
- } else {
- return 0;
- }
- }
- }
-
- /**
- * Note: this comparator imposes orderings that are inconsistent with equals.
- */
- private static class PhoneConfigComparator implements Comparator<ConfigMatch> {
-
- private final SparseIntArray mDensitySort = new SparseIntArray(4);
-
- public PhoneConfigComparator() {
- // put the sort order for the density.
- mDensitySort.put(Density.HIGH.getDpiValue(), 1);
- mDensitySort.put(Density.MEDIUM.getDpiValue(), 2);
- mDensitySort.put(Density.XHIGH.getDpiValue(), 3);
- mDensitySort.put(Density.LOW.getDpiValue(), 4);
- }
-
- @Override
- public int compare(ConfigMatch o1, ConfigMatch o2) {
- FolderConfiguration config1 = o1 != null ? o1.testConfig : null;
- FolderConfiguration config2 = o2 != null ? o2.testConfig : null;
- if (config1 == null) {
- if (config2 == null) {
- return 0;
- } else {
- return -1;
- }
- } else if (config2 == null) {
- return 1;
- }
-
- int dpi1 = Density.DEFAULT_DENSITY;
- int dpi2 = Density.DEFAULT_DENSITY;
-
- DensityQualifier dpiQualifier1 = config1.getDensityQualifier();
- if (dpiQualifier1 != null) {
- Density value = dpiQualifier1.getValue();
- dpi1 = value != null ? value.getDpiValue() : Density.DEFAULT_DENSITY;
- }
- dpi1 = mDensitySort.get(dpi1, 100 /* valueIfKeyNotFound*/);
-
- DensityQualifier dpiQualifier2 = config2.getDensityQualifier();
- if (dpiQualifier2 != null) {
- Density value = dpiQualifier2.getValue();
- dpi2 = value != null ? value.getDpiValue() : Density.DEFAULT_DENSITY;
- }
- dpi2 = mDensitySort.get(dpi2, 100 /* valueIfKeyNotFound*/);
-
- if (dpi1 == dpi2) {
- // portrait is better
- ScreenOrientation so1 = ScreenOrientation.PORTRAIT;
- ScreenOrientationQualifier orientationQualifier1 =
- config1.getScreenOrientationQualifier();
- if (orientationQualifier1 != null) {
- so1 = orientationQualifier1.getValue();
- if (so1 == null) {
- so1 = ScreenOrientation.PORTRAIT;
- }
- }
- ScreenOrientation so2 = ScreenOrientation.PORTRAIT;
- ScreenOrientationQualifier orientationQualifier2 =
- config2.getScreenOrientationQualifier();
- if (orientationQualifier2 != null) {
- so2 = orientationQualifier2.getValue();
- if (so2 == null) {
- so2 = ScreenOrientation.PORTRAIT;
- }
- }
-
- if (so1 == ScreenOrientation.PORTRAIT) {
- if (so2 == ScreenOrientation.PORTRAIT) {
- return 0;
- } else {
- return -1;
- }
- } else if (so2 == ScreenOrientation.PORTRAIT) {
- return 1;
- } else {
- return 0;
- }
- }
-
- return dpi1 - dpi2;
- }
- }
-}