Home | History | Annotate | Download | only in configuration
      1 /*
      2  * Copyright (C) 2017 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 #ifndef AAPT2_CONFIGURATION_H
     18 #define AAPT2_CONFIGURATION_H
     19 
     20 #include <string>
     21 #include <unordered_map>
     22 #include <vector>
     23 
     24 #include "ConfigDescription.h"
     25 #include "Diagnostics.h"
     26 #include "util/Maybe.h"
     27 
     28 namespace aapt {
     29 
     30 namespace configuration {
     31 
     32 /** A mapping of group labels to group of configuration items. */
     33 template<class T>
     34 using Group = std::unordered_map<std::string, std::vector<T>>;
     35 
     36 /** Output artifact configuration options. */
     37 struct Artifact {
     38   /** Name to use for output of processing foo.apk -> foo.<name>.apk. */
     39   std::string name;
     40   /** If present, uses the ABI group with this name. */
     41   Maybe<std::string> abi_group;
     42   /** If present, uses the screen density group with this name. */
     43   Maybe<std::string> screen_density_group;
     44   /** If present, uses the locale group with this name. */
     45   Maybe<std::string> locale_group;
     46   /** If present, uses the Android SDK group with this name. */
     47   Maybe<std::string> android_sdk_group;
     48   /** If present, uses the device feature group with this name. */
     49   Maybe<std::string> device_feature_group;
     50   /** If present, uses the OpenGL texture group with this name. */
     51   Maybe<std::string> gl_texture_group;
     52 
     53   /** Convert an artifact name template into a name string based on configuration contents. */
     54   Maybe<std::string> ToArtifactName(const std::string& format, IDiagnostics* diag) const;
     55 };
     56 
     57 /** Enumeration of currently supported ABIs. */
     58 enum class Abi {
     59   kArmeV6,
     60   kArmV7a,
     61   kArm64V8a,
     62   kX86,
     63   kX86_64,
     64   kMips,
     65   kMips64,
     66   kUniversal
     67 };
     68 
     69 /** Helper method to convert an ABI to a string representing the path within the APK. */
     70 const std::string& AbiToString(Abi abi);
     71 
     72 /**
     73  * Represents an individual locale. When a locale is included, it must be
     74  * declared from least specific to most specific, as a region does not make
     75  * sense without a language. If neither the language or region are specified it
     76  * acts as a special case for catch all. This can allow all locales to be kept,
     77  * or compressed.
     78  */
     79 struct Locale {
     80   /** The ISO<?> standard locale language code. */
     81   Maybe<std::string> lang;
     82   /** The ISO<?> standard locale region code. */
     83   Maybe<std::string> region;
     84 
     85   inline friend bool operator==(const Locale& lhs, const Locale& rhs) {
     86     return lhs.lang == rhs.lang && lhs.region == rhs.region;
     87   }
     88 };
     89 
     90 // TODO: Encapsulate manifest modifications from the configuration file.
     91 struct AndroidManifest {
     92   inline friend bool operator==(const AndroidManifest& lhs, const AndroidManifest& rhs) {
     93     return true;  // nothing to compare yet.
     94   }
     95 };
     96 
     97 struct AndroidSdk {
     98   Maybe<std::string> min_sdk_version;
     99   Maybe<std::string> target_sdk_version;
    100   Maybe<std::string> max_sdk_version;
    101   Maybe<AndroidManifest> manifest;
    102 
    103   inline friend bool operator==(const AndroidSdk& lhs, const AndroidSdk& rhs) {
    104     return lhs.min_sdk_version == rhs.min_sdk_version &&
    105         lhs.target_sdk_version == rhs.target_sdk_version &&
    106         lhs.max_sdk_version == rhs.max_sdk_version &&
    107         lhs.manifest == rhs.manifest;
    108   }
    109 };
    110 
    111 // TODO: Make device features more than just an arbitrary string?
    112 using DeviceFeature = std::string;
    113 
    114 /** Represents a mapping of texture paths to a GL texture format. */
    115 struct GlTexture {
    116   std::string name;
    117   std::vector<std::string> texture_paths;
    118 
    119   inline friend bool operator==(const GlTexture& lhs, const GlTexture& rhs) {
    120     return lhs.name == rhs.name && lhs.texture_paths == rhs.texture_paths;
    121   }
    122 };
    123 
    124 /** AAPT2 XML configuration file binary representation. */
    125 struct PostProcessingConfiguration {
    126   // TODO: Support named artifacts?
    127   std::vector<Artifact> artifacts;
    128   Maybe<std::string> artifact_format;
    129 
    130   Group<Abi> abi_groups;
    131   Group<ConfigDescription> screen_density_groups;
    132   Group<Locale> locale_groups;
    133   Group<AndroidSdk> android_sdk_groups;
    134   Group<DeviceFeature> device_feature_groups;
    135   Group<GlTexture> gl_texture_groups;
    136 };
    137 
    138 }  // namespace configuration
    139 
    140 // Forward declaration of classes used in the API.
    141 struct IDiagnostics;
    142 namespace xml {
    143 class Element;
    144 }
    145 
    146 /**
    147  * XML configuration file parser for the split and optimize commands.
    148  */
    149 class ConfigurationParser {
    150  public:
    151 
    152   /** Returns a ConfigurationParser for the file located at the provided path. */
    153   static Maybe<ConfigurationParser> ForPath(const std::string& path);
    154 
    155   /** Returns a ConfigurationParser for the configuration in the provided file contents. */
    156   static ConfigurationParser ForContents(const std::string& contents) {
    157     ConfigurationParser parser{contents};
    158     return parser;
    159   }
    160 
    161   /** Sets the diagnostics context to use when parsing. */
    162   ConfigurationParser& WithDiagnostics(IDiagnostics* diagnostics) {
    163     diag_ = diagnostics;
    164     return *this;
    165   }
    166 
    167   /**
    168    * Parses the configuration file and returns the results. If the configuration could not be parsed
    169    * the result is empty and any errors will be displayed with the provided diagnostics context.
    170    */
    171   Maybe<configuration::PostProcessingConfiguration> Parse();
    172 
    173  protected:
    174   /**
    175    * Instantiates a new ConfigurationParser with the provided configuration file and a no-op
    176    * diagnostics context. The default diagnostics context can be overridden with a call to
    177    * WithDiagnostics(IDiagnostics *).
    178    */
    179   explicit ConfigurationParser(std::string contents);
    180 
    181   /** Returns the current diagnostics context to any subclasses. */
    182   IDiagnostics* diagnostics() {
    183     return diag_;
    184   }
    185 
    186   /**
    187    * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
    188    * element was successfully processed, otherwise returns false.
    189    */
    190   using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
    191                                            xml::Element* element, IDiagnostics* diag)>;
    192 
    193   /** Handler for <artifact> tags. */
    194   static ActionHandler artifact_handler_;
    195   /** Handler for <artifact-format> tags. */
    196   static ActionHandler artifact_format_handler_;
    197   /** Handler for <abi-group> tags. */
    198   static ActionHandler abi_group_handler_;
    199   /** Handler for <screen-density-group> tags. */
    200   static ActionHandler screen_density_group_handler_;
    201   /** Handler for <locale-group> tags. */
    202   static ActionHandler locale_group_handler_;
    203   /** Handler for <android-sdk-group> tags. */
    204   static ActionHandler android_sdk_group_handler_;
    205   /** Handler for <gl-texture-group> tags. */
    206   static ActionHandler gl_texture_group_handler_;
    207   /** Handler for <device-feature-group> tags. */
    208   static ActionHandler device_feature_group_handler_;
    209 
    210  private:
    211   /** The contents of the configuration file to parse. */
    212   const std::string contents_;
    213   /** The diagnostics context to send messages to. */
    214   IDiagnostics* diag_;
    215 };
    216 
    217 }  // namespace aapt
    218 
    219 #endif  // AAPT2_CONFIGURATION_H
    220