ConfigDescription.h revision b58c3ef023acf3851e4a0557d04d65d52835d2df
16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_CONFIG_DESCRIPTION_H
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_CONFIG_DESCRIPTION_H
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <ostream>
216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h"
23d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h"
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
27bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski/*
28bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * Subclass of ResTable_config that adds convenient
29bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * initialization and comparison methods.
30bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski */
316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct ConfigDescription : public android::ResTable_config {
32bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
33bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * Returns an immutable default config.
34bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  static const ConfigDescription& DefaultConfig();
36cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
37bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /*
38bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * Parse a string of the form 'fr-sw600dp-land' and fill in the
39bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * given ResTable_config with resulting configuration parameters.
40bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   *
41bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * The resulting configuration has the appropriate sdkVersion defined
42bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * for backwards compatibility.
43bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
44d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  static bool Parse(const android::StringPiece& str, ConfigDescription* out = nullptr);
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
46bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
47bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * If the configuration uses an axis that was added after
48bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * the original Android release, make sure the SDK version
49bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * is set accordingly.
50bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  static void ApplyVersionForCompatibility(ConfigDescription* config);
52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription();
54cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription(const android::ResTable_config& o);  // NOLINT(implicit)
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription(const ConfigDescription& o);
56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription(ConfigDescription&& o);
57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription& operator=(const android::ResTable_config& o);
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription& operator=(const ConfigDescription& o);
60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription& operator=(ConfigDescription&& o);
61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ConfigDescription CopyWithoutSdkVersion() const;
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
64b58c3ef023acf3851e4a0557d04d65d52835d2dfAdam Lesinski  // Returns the BCP-47 language tag of this configuration's locale.
65b58c3ef023acf3851e4a0557d04d65d52835d2dfAdam Lesinski  std::string GetBcp47LanguageTag(bool canonicalize = false) const;
66b58c3ef023acf3851e4a0557d04d65d52835d2dfAdam Lesinski
67bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
68bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * A configuration X dominates another configuration Y, if X has at least the
69bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * precedence of Y and X is strictly more general than Y: for any type defined
70bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * by X, the same type is defined by Y with a value equal to or, in the case
71bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * of ranges, more specific than that of X.
72bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   *
73bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It
74bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'.
75bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool Dominates(const ConfigDescription& o) const;
77cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
78bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
79bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * Returns true if this configuration defines a more important configuration
80bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * parameter than o. For example, "en" has higher precedence than "v23",
81bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * whereas "en" has the same precedence as "en-v23".
82bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
83ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool HasHigherPrecedenceThan(const ConfigDescription& o) const;
84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
85bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
86bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * A configuration conflicts with another configuration if both
87bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * configurations define an incompatible configuration parameter. An
88bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * incompatible configuration parameter is a non-range, non-density parameter
89bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * that is defined in both configurations as a different, non-default value.
90bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool ConflictsWith(const ConfigDescription& o) const;
92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
93bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  /**
94bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * A configuration is compatible with another configuration if both
95bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * configurations can match a common concrete device configuration and are
96bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * unrelated by domination. For example, land-v11 conflicts with port-v21
97bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   * but is compatible with v21 (both land-v11 and v21 would match en-land-v23).
98bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski   */
99ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool IsCompatibleWith(const ConfigDescription& o) const;
100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
101ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  bool MatchWithDensity(const ConfigDescription& o) const;
102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
103cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator<(const ConfigDescription& o) const;
104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator<=(const ConfigDescription& o) const;
105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator==(const ConfigDescription& o) const;
106cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator!=(const ConfigDescription& o) const;
107cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator>=(const ConfigDescription& o) const;
108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator>(const ConfigDescription& o) const;
1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription() {
112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  memset(this, 0, sizeof(*this));
113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const android::ResTable_config& o) {
117cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
118cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
122cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(ConfigDescription&& o) {
126cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *this = o;
1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
129bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(
130bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski    const android::ResTable_config& o) {
131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
132cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
136bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(
137bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski    const ConfigDescription& o) {
138cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) {
143cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *this = o;
144cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
147bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline bool ConfigDescription::MatchWithDensity(
148bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski    const ConfigDescription& o) const {
149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return match(o) && (density == 0 || density == o.density);
15077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
15177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<(const ConfigDescription& o) const {
153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) < 0;
1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<=(const ConfigDescription& o) const {
157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) <= 0;
1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator==(const ConfigDescription& o) const {
161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) == 0;
1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator!=(const ConfigDescription& o) const {
165cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) != 0;
1666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>=(const ConfigDescription& o) const {
169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) >= 0;
1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>(const ConfigDescription& o) const {
173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) > 0;
1746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
177bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski                                  const ConfigDescription& o) {
178bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski  return out << o.toString().string();
179bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski}
180bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski
181cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
183cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif  // AAPT_CONFIG_DESCRIPTION_H
184