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