diff options
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/FullyQualifiedName.java | 88 | ||||
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/ParsedAndroidData.java | 24 |
2 files changed, 74 insertions, 38 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/FullyQualifiedName.java b/src/tools/android/java/com/google/devtools/build/android/FullyQualifiedName.java index 2678706d21..072b9d5683 100644 --- a/src/tools/android/java/com/google/devtools/build/android/FullyQualifiedName.java +++ b/src/tools/android/java/com/google/devtools/build/android/FullyQualifiedName.java @@ -22,9 +22,7 @@ import com.google.common.collect.Iterators; import com.google.common.collect.PeekingIterator; import com.google.devtools.build.android.proto.SerializeFormat; -import com.android.ide.common.resources.configuration.CountryCodeQualifier; import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.ide.common.resources.configuration.NetworkCodeQualifier; import com.android.ide.common.resources.configuration.ResourceQualifier; import com.android.resources.ResourceType; @@ -99,19 +97,18 @@ public class FullyQualifiedName implements DataKey, Comparable<FullyQualifiedNam } private static List<String> getQualifiers(String[] dirNameAndQualifiers) { - // TODO(corysmith): Remove when FolderConfiguration supports ll-r{3,4} regions. PeekingIterator<String> rawQualifiers = Iterators.peekingIterator(Iterators.forArray(dirNameAndQualifiers)); // Remove directory name rawQualifiers.next(); List<String> unHandledLanguageRegionQualifiers = new ArrayList<>(); + List<String> unHandledDensityQualifiers = new ArrayList<>(); + List<String> unHandledUIModeQualifiers = new ArrayList<>(); List<String> handledQualifiers = new ArrayList<>(); - // The language/region qualifiers can be in the first 4 qualifier slots. - for (int qualifierSlot = 0; qualifierSlot < 4; qualifierSlot++) { - // qualifiers have been exhausted. - if (!rawQualifiers.hasNext()) { - break; - } + // TODO(corysmith): Remove when FolderConfiguration is updated to handle anydpi and + // BCP prefixes. + // The language/region qualifiers and anydpi cannot be currently handled. + while (rawQualifiers.hasNext()) { String qualifier = rawQualifiers.next(); if (qualifier.startsWith(BCP_PREFIX)) { // The b+local+script/region can't be handled. @@ -130,12 +127,15 @@ public class FullyQualifiedName implements DataKey, Comparable<FullyQualifiedNam unHandledLanguageRegionQualifiers.add("b+sr+Latn"); // Consume the next value, as it's been replaced. rawQualifiers.next(); + } else if (qualifier.equals("anydpi")) { + unHandledDensityQualifiers.add(qualifier); + } else if (qualifier.equals("watch")) { + unHandledUIModeQualifiers.add(qualifier); } else { // This qualifier can probably be handled by FolderConfiguration. handledQualifiers.add(qualifier); } } - Iterators.addAll(handledQualifiers, rawQualifiers); // Create a configuration FolderConfiguration config = FolderConfiguration.getConfigFromQualifiers(handledQualifiers); // FolderConfiguration returns an unhelpful null when it considers the qualifiers to be @@ -145,29 +145,53 @@ public class FullyQualifiedName implements DataKey, Comparable<FullyQualifiedNam String.format(INVALID_QUALIFIERS, DASH_JOINER.join(dirNameAndQualifiers))); } config.normalize(); - PeekingIterator<ResourceQualifier> normalizedQualifiers = - Iterators.peekingIterator(Iterators.forArray(config.getQualifiers())); - // No qualifiers, just returns the language regions. Which may be empty, but an empty list is - // an empty list. - if (!normalizedQualifiers.hasNext()) { - return ImmutableList.copyOf(unHandledLanguageRegionQualifiers); + + // This is fragile but better than the Gradle scheme of just dropping + // entire subtrees. + Builder<String> builder = ImmutableList.<String>builder(); + addIfNotNull(config.getCountryCodeQualifier(), builder); + addIfNotNull(config.getNetworkCodeQualifier(), builder); + if (unHandledLanguageRegionQualifiers.isEmpty()) { + addIfNotNull(config.getLanguageQualifier(), builder); + addIfNotNull(config.getRegionQualifier(), builder); + } else { + builder.addAll(unHandledLanguageRegionQualifiers); } - Builder<String> finalQualifiers = ImmutableList.<String>builder(); - while (normalizedQualifiers.hasNext()) { - // The Mobile Country Code and Mobile Network Code will always come before the unhandled - // qualifiers. - if (normalizedQualifiers.peek() instanceof CountryCodeQualifier - || normalizedQualifiers.peek() instanceof NetworkCodeQualifier) { - finalQualifiers.add(QUALIFIER_TO_STRING.apply(normalizedQualifiers.next())); - } else { - // Exit the loop to add the rest of the qualifiers. - break; - } + addIfNotNull(config.getLayoutDirectionQualifier(), builder); + addIfNotNull(config.getSmallestScreenWidthQualifier(), builder); + addIfNotNull(config.getScreenWidthQualifier(), builder); + addIfNotNull(config.getScreenHeightQualifier(), builder); + addIfNotNull(config.getScreenSizeQualifier(), builder); + addIfNotNull(config.getScreenRatioQualifier(), builder); + addIfNotNull(config.getScreenRoundQualifier(), builder); + addIfNotNull(config.getScreenOrientationQualifier(), builder); + if (unHandledUIModeQualifiers.isEmpty()) { + addIfNotNull(config.getUiModeQualifier(), builder); + } else { + builder.addAll(unHandledUIModeQualifiers); + } + addIfNotNull(config.getNightModeQualifier(), builder); + if (unHandledDensityQualifiers.isEmpty()) { + addIfNotNull(config.getDensityQualifier(), builder); + } else { + builder.addAll(unHandledDensityQualifiers); + } + addIfNotNull(config.getTouchTypeQualifier(), builder); + addIfNotNull(config.getKeyboardStateQualifier(), builder); + addIfNotNull(config.getTextInputMethodQualifier(), builder); + addIfNotNull(config.getNavigationStateQualifier(), builder); + addIfNotNull(config.getNavigationMethodQualifier(), builder); + addIfNotNull(config.getScreenDimensionQualifier(), builder); + addIfNotNull(config.getVersionQualifier(), builder); + + return builder.build(); + } + + private static void addIfNotNull( + ResourceQualifier qualifier, ImmutableList.Builder<String> builder) { + if (qualifier != null) { + builder.add(qualifier.getFolderSegment()); } - finalQualifiers.addAll(unHandledLanguageRegionQualifiers); - // Consume the rest of the qualifers without care. - finalQualifiers.addAll(Iterators.transform(normalizedQualifiers, QUALIFIER_TO_STRING)); - return finalQualifiers.build(); } public static Factory from(List<String> qualifiers, String pkg) { @@ -202,7 +226,7 @@ public class FullyQualifiedName implements DataKey, Comparable<FullyQualifiedNam String parsedPackage = matcher.group("package"); ResourceType resourceType = ResourceType.getEnum(matcher.group("type")); String resourceName = matcher.group("name"); - + if (resourceType == null || resourceName == null) { throw new IllegalArgumentException( String.format( diff --git a/src/tools/android/java/com/google/devtools/build/android/ParsedAndroidData.java b/src/tools/android/java/com/google/devtools/build/android/ParsedAndroidData.java index 0ec40d8aa3..4e78428b88 100644 --- a/src/tools/android/java/com/google/devtools/build/android/ParsedAndroidData.java +++ b/src/tools/android/java/com/google/devtools/build/android/ParsedAndroidData.java @@ -21,6 +21,7 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.android.xml.StyleableXmlResourceValue; import com.android.ide.common.res2.MergingException; +import com.android.resources.ResourceFolderType; import java.io.IOException; import java.nio.file.FileVisitOption; @@ -37,6 +38,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.logging.Logger; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.NotThreadSafe; @@ -52,6 +54,7 @@ import javax.xml.stream.XMLStreamException; */ @Immutable public class ParsedAndroidData { + private static final Logger logger = Logger.getLogger(ParsedAndroidData.class.getCanonicalName()); @NotThreadSafe static class Builder { @@ -242,7 +245,7 @@ public class ParsedAndroidData { private final KeyValueConsumer<DataKey, DataResource> overwritingConsumer; private final KeyValueConsumer<DataKey, DataResource> combiningResources; private final List<Exception> errors; - private boolean inValuesSubtree; + private ResourceFolderType folderType; private FullyQualifiedName.Factory fqnFactory; private final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory(); @@ -276,19 +279,28 @@ public class ParsedAndroidData { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { final String[] dirNameAndQualifiers = dir.getFileName().toString().split("-"); - inValuesSubtree = "values".equals(dirNameAndQualifiers[0]); - fqnFactory = FullyQualifiedName.Factory.fromDirectoryName(dirNameAndQualifiers); - return FileVisitResult.CONTINUE; + folderType = ResourceFolderType.getTypeByName(dirNameAndQualifiers[0]); + if (folderType == null) { + return FileVisitResult.CONTINUE; + } + try { + fqnFactory = FullyQualifiedName.Factory.fromDirectoryName(dirNameAndQualifiers); + return FileVisitResult.CONTINUE; + } catch (IllegalArgumentException e) { + logger.warning( + String.format("%s is an invalid resource directory due to %s", dir, e.getMessage())); + return FileVisitResult.SKIP_SUBTREE; + } } @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { try { if (!Files.isDirectory(path) && !path.getFileName().toString().startsWith(".")) { - if (inValuesSubtree) { + if (folderType == ResourceFolderType.VALUES) { DataResourceXml.parse( xmlInputFactory, path, fqnFactory, overwritingConsumer, combiningResources); - } else { + } else if (folderType != null) { String rawFqn = deriveRawFullyQualifiedName(path); FullyQualifiedName key = fqnFactory.parse(rawFqn); overwritingConsumer.consume(key, DataValueFile.of(path)); |