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 6793190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski std::string to_string() const; 6893190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski 69bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski /** 70bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * A configuration X dominates another configuration Y, if X has at least the 71bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * precedence of Y and X is strictly more general than Y: for any type defined 72bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * by X, the same type is defined by Y with a value equal to or, in the case 73bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * of ranges, more specific than that of X. 74bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * 75bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It 76bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'. 77bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski */ 78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool Dominates(const ConfigDescription& o) const; 79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 80bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski /** 81bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * Returns true if this configuration defines a more important configuration 82bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * parameter than o. For example, "en" has higher precedence than "v23", 83bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * whereas "en" has the same precedence as "en-v23". 84bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski */ 85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool HasHigherPrecedenceThan(const ConfigDescription& o) const; 86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 87bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski /** 88bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * A configuration conflicts with another configuration if both 89bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * configurations define an incompatible configuration parameter. An 90bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * incompatible configuration parameter is a non-range, non-density parameter 91bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * that is defined in both configurations as a different, non-default value. 92bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski */ 93ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool ConflictsWith(const ConfigDescription& o) const; 94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 95bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski /** 96bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * A configuration is compatible with another configuration if both 97bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * configurations can match a common concrete device configuration and are 98bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * unrelated by domination. For example, land-v11 conflicts with port-v21 99bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski * but is compatible with v21 (both land-v11 and v21 would match en-land-v23). 100bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski */ 101ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool IsCompatibleWith(const ConfigDescription& o) const; 102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 103ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool MatchWithDensity(const ConfigDescription& o) const; 104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 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; 109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator>=(const ConfigDescription& o) const; 110cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator>(const ConfigDescription& o) const; 1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription() { 114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski memset(this, 0, sizeof(*this)); 115cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size = sizeof(android::ResTable_config); 1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const android::ResTable_config& o) { 119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *static_cast<android::ResTable_config*>(this) = o; 120cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size = sizeof(android::ResTable_config); 1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(const ConfigDescription& o) { 124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *static_cast<android::ResTable_config*>(this) = o; 1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription::ConfigDescription(ConfigDescription&& o) { 128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *this = o; 1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 131bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=( 132bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski const android::ResTable_config& o) { 133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *static_cast<android::ResTable_config*>(this) = o; 134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size = sizeof(android::ResTable_config); 135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return *this; 1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 138bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=( 139bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski const ConfigDescription& o) { 140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *static_cast<android::ResTable_config*>(this) = o; 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return *this; 1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) { 145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski *this = o; 146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return *this; 1476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 149bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline bool ConfigDescription::MatchWithDensity( 150bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski const ConfigDescription& o) const { 151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return match(o) && (density == 0 || density == o.density); 15277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall} 15377788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall 1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<(const ConfigDescription& o) const { 155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) < 0; 1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator<=(const ConfigDescription& o) const { 159cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) <= 0; 1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator==(const ConfigDescription& o) const { 163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) == 0; 1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator!=(const ConfigDescription& o) const { 167cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) != 0; 1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>=(const ConfigDescription& o) const { 171cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) >= 0; 1726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool ConfigDescription::operator>(const ConfigDescription& o) const { 175cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(o) > 0; 1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 178bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out, 179bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski const ConfigDescription& o) { 180bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski return out << o.toString().string(); 181bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski} 182bb94f32a0042c8e2ab3d6e0de1b693713d2a6eabAdam Lesinski 183cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 185cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif // AAPT_CONFIG_DESCRIPTION_H 186