ConfigDescription.h revision cacb28f2d60858106e2819cc7d95a65e8bda890b
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
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/StringPiece.h"
216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <androidfw/ResourceTypes.h>
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <ostream>
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Subclass of ResTable_config that adds convenient
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * initialization and comparison methods.
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct ConfigDescription : public android::ResTable_config {
32cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
33cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * Returns an immutable default config.
34cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
35cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  static const ConfigDescription& defaultConfig();
36cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
37cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /*
38cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * Parse a string of the form 'fr-sw600dp-land' and fill in the
39cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * given ResTable_config with resulting configuration parameters.
40cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   *
41cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * The resulting configuration has the appropriate sdkVersion defined
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * for backwards compatibility.
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  static bool parse(const StringPiece& str, ConfigDescription* out = nullptr);
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * If the configuration uses an axis that was added after
48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * the original Android release, make sure the SDK version
49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * is set accordingly.
50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam 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
62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription copyWithoutSdkVersion() const;
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * A configuration X dominates another configuration Y, if X has at least the
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * precedence of Y and X is strictly more general than Y: for any type defined
67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * by X, the same type is defined by Y with a value equal to or, in the case
68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * of ranges, more specific than that of X.
69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   *
70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It
71cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'.
72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
73cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool dominates(const ConfigDescription& o) const;
74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * Returns true if this configuration defines a more important configuration
77cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * parameter than o. For example, "en" has higher precedence than "v23",
78cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * whereas "en" has the same precedence as "en-v23".
79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool hasHigherPrecedenceThan(const ConfigDescription& o) const;
81cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
82cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * A configuration conflicts with another configuration if both
84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * configurations define an incompatible configuration parameter. An
85cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * incompatible configuration parameter is a non-range, non-density parameter
86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * that is defined in both configurations as a different, non-default value.
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
88cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool conflictsWith(const ConfigDescription& o) const;
89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  /**
91cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * A configuration is compatible with another configuration if both
92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * configurations can match a common concrete device configuration and are
93cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * unrelated by domination. For example, land-v11 conflicts with port-v21
94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   * but is compatible with v21 (both land-v11 and v21 would match en-land-v23).
95cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   */
96cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool isCompatibleWith(const ConfigDescription& o) const;
97cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
98cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool matchWithDensity(const ConfigDescription& o) const;
99cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator<(const ConfigDescription& o) const;
101cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator<=(const ConfigDescription& o) const;
102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator==(const ConfigDescription& o) const;
103cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator!=(const ConfigDescription& o) const;
104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator>=(const ConfigDescription& o) const;
105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  bool operator>(const ConfigDescription& o) const;
1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription() {
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  memset(this, 0, sizeof(*this));
110cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const android::ResTable_config& o) {
114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
115cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(ConfigDescription&& o) {
123cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *this = o;
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
126cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(
127cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    const android::ResTable_config& o) {
128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
129cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  size = sizeof(android::ResTable_config);
130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(
134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    const ConfigDescription& o) {
135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *static_cast<android::ResTable_config*>(this) = o;
136cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) {
140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  *this = o;
141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this;
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
144cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline bool ConfigDescription::matchWithDensity(
145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    const ConfigDescription& o) const {
146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return match(o) && (density == 0 || density == o.density);
14777788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
14877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<(const ConfigDescription& o) const {
150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) < 0;
1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<=(const ConfigDescription& o) const {
154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) <= 0;
1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator==(const ConfigDescription& o) const {
158cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) == 0;
1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator!=(const ConfigDescription& o) const {
162cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) != 0;
1636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>=(const ConfigDescription& o) const {
166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) >= 0;
1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>(const ConfigDescription& o) const {
170cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return compare(o) > 0;
1716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out,
174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                  const ConfigDescription& o) {
175cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return out << o.toString().string();
1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
178cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
180cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif  // AAPT_CONFIG_DESCRIPTION_H
181