diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 86732196518c3..65160d5bf8586 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1195,6 +1195,12 @@ struct ResTable_config
// Example: en-US, en-Latn-US, en-POSIX.
void getBcp47Locale(char* out) const;
+ // Append to str the resource-qualifer string representation of the
+ // locale component of this Config. If the locale is only country
+ // and language, it will look like en-rUS. If it has scripts and
+ // variants, it will be a modified bcp47 tag: b+en+Latn+US.
+ void appendDirLocale(String8& str) const;
+
// Sets the values of language, region, script and variant to the
// well formed BCP-47 locale contained in |in|. The input locale is
// assumed to be valid and no validation is performed.
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index d5d583c7ae148..e2471505182c6 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -2550,6 +2550,58 @@ bool ResTable_config::match(const ResTable_config& settings) const {
return true;
}
+void ResTable_config::appendDirLocale(String8& out) const {
+ if (!language[0]) {
+ return;
+ }
+
+ if (!localeScript[0] && !localeVariant[0]) {
+ // Legacy format.
+ if (out.size() > 0) {
+ out.append("-");
+ }
+
+ char buf[4];
+ size_t len = unpackLanguage(buf);
+ out.append(buf, len);
+
+ if (country[0]) {
+ out.append("-r");
+ len = unpackRegion(buf);
+ out.append(buf, len);
+ }
+ return;
+ }
+
+ // We are writing the modified bcp47 tag.
+ // It starts with 'b+' and uses '+' as a separator.
+
+ if (out.size() > 0) {
+ out.append("-");
+ }
+ out.append("b+");
+
+ char buf[4];
+ size_t len = unpackLanguage(buf);
+ out.append(buf, len);
+
+ if (localeScript[0]) {
+ out.append("+");
+ out.append(localeScript, sizeof(localeScript));
+ }
+
+ if (country[0]) {
+ out.append("+");
+ len = unpackRegion(buf);
+ out.append(buf, len);
+ }
+
+ if (localeVariant[0]) {
+ out.append("+");
+ out.append(localeVariant, sizeof(localeVariant));
+ }
+}
+
void ResTable_config::getBcp47Locale(char str[RESTABLE_MAX_LOCALE_LEN]) const {
memset(str, 0, RESTABLE_MAX_LOCALE_LEN);
@@ -2650,12 +2702,7 @@ String8 ResTable_config::toString() const {
res.appendFormat("mnc%d", dtohs(mnc));
}
- char localeStr[RESTABLE_MAX_LOCALE_LEN];
- getBcp47Locale(localeStr);
- if (strlen(localeStr) > 0) {
- if (res.size() > 0) res.append("-");
- res.append(localeStr);
- }
+ appendDirLocale(res);
if ((screenLayout&MASK_LAYOUTDIR) != 0) {
if (res.size() > 0) res.append("-");
diff --git a/tests/Split/res/values-b+fr+Latn+CA/strings.xml b/tests/Split/res/values-b+fr+Latn+CA/strings.xml
new file mode 100644
index 0000000000000..108a13565794b
--- /dev/null
+++ b/tests/Split/res/values-b+fr+Latn+CA/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Bonsoir!
+
diff --git a/tests/Split/res/values-fr-rCA/strings.xml b/tests/Split/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000000000..0837a68a30b66
--- /dev/null
+++ b/tests/Split/res/values-fr-rCA/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Bonjour
+
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 871e04f7aa9d5..d346731e63e22 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -367,33 +367,6 @@ int AaptLocaleValue::initFromDirName(const Vector& parts, const int sta
return currentIndex;
}
-
-String8 AaptLocaleValue::toDirName() const {
- String8 dirName("");
- if (language[0]) {
- dirName += language;
- } else {
- return dirName;
- }
-
- if (script[0]) {
- dirName += "-s";
- dirName += script;
- }
-
- if (region[0]) {
- dirName += "-r";
- dirName += region;
- }
-
- if (variant[0]) {
- dirName += "-v";
- dirName += variant;
- }
-
- return dirName;
-}
-
void AaptLocaleValue::initFromResTable(const ResTable_config& config) {
config.unpackLanguage(language);
config.unpackRegion(region);
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 7ae5368d80bde..4fdc9640e8e55 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -78,8 +78,6 @@ struct AaptLocaleValue {
void writeTo(ResTable_config* out) const;
- String8 toDirName() const;
-
int compare(const AaptLocaleValue& other) const {
return memcmp(this, &other, sizeof(AaptLocaleValue));
}
diff --git a/tools/aapt/tests/AaptConfig_test.cpp b/tools/aapt/tests/AaptConfig_test.cpp
index ef3860c72921a..7618974db3299 100644
--- a/tools/aapt/tests/AaptConfig_test.cpp
+++ b/tools/aapt/tests/AaptConfig_test.cpp
@@ -65,7 +65,7 @@ TEST(AaptConfigTest, ParseBasicQualifiers) {
TEST(AaptConfigTest, ParseLocales) {
ConfigDescription config;
EXPECT_TRUE(TestParse("en-rUS", &config));
- EXPECT_EQ(String8("en-US"), config.toString());
+ EXPECT_EQ(String8("en-rUS"), config.toString());
}
TEST(AaptConfigTest, ParseQualifierAddedInApi13) {