Loading core/java/android/app/ResourcesManager.java +217 −183 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.res.ResourcesImpl; import android.content.res.ResourcesKey; import android.hardware.display.DisplayManagerGlobal; import android.os.IBinder; import android.os.Trace; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.LocaleList; Loading Loading @@ -430,6 +431,9 @@ public class ResourcesManager { @Nullable Configuration overrideConfig, @NonNull CompatibilityInfo compatInfo, @Nullable ClassLoader classLoader) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#createBaseActivityResources"); final ResourcesKey key = new ResourcesKey( resDir, splitResDirs, Loading @@ -446,7 +450,8 @@ public class ResourcesManager { } synchronized (this) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); if (overrideConfig != null) { Loading @@ -461,6 +466,9 @@ public class ResourcesManager { // Now request an actual Resources object. return getOrCreateResources(activityToken, key, classLoader); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** Loading Loading @@ -490,8 +498,8 @@ public class ResourcesManager { } if (activityToken != null) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(activityToken); // Clean up any dead references so they don't pile up. ArrayUtils.unstableRemoveIf(activityResources.activityResources, Loading Loading @@ -539,6 +547,7 @@ public class ResourcesManager { final String[] systemLocales = findSystemLocales ? AssetManager.getSystem().getLocales() : null; final String[] nonSystemLocales = resourcesImpl.getAssets().getNonSystemLocales(); // Avoid checking for non-pseudo-locales if we already know there were some from a previous // Resources. The default value (for when hasNonSystemLocales is true) doesn't matter, // since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be Loading Loading @@ -613,6 +622,8 @@ public class ResourcesManager { @Nullable Configuration overrideConfig, @NonNull CompatibilityInfo compatInfo, @Nullable ClassLoader classLoader) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources"); final ResourcesKey key = new ResourcesKey( resDir, splitResDirs, Loading @@ -623,6 +634,9 @@ public class ResourcesManager { compatInfo); classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader(); return getOrCreateResources(activityToken, key, classLoader); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** Loading @@ -636,9 +650,12 @@ public class ResourcesManager { */ public void updateResourcesForActivity(@NonNull IBinder activityToken, @Nullable Configuration overrideConfig) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#updateResourcesForActivity"); synchronized (this) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(activityToken); if (Objects.equals(activityResources.overrideConfig, overrideConfig)) { // They are the same, no work to do. Loading @@ -660,9 +677,11 @@ public class ResourcesManager { Throwable here = new Throwable(); here.fillInStackTrace(); Slog.d(TAG, "updating resources override for activity=" + activityToken + " from oldConfig=" + Configuration.resourceQualifierString(oldConfig) + " from oldConfig=" + Configuration.resourceQualifierString(oldConfig) + " to newConfig=" + Configuration.resourceQualifierString(activityResources.overrideConfig), + Configuration.resourceQualifierString( activityResources.overrideConfig), here); } Loading @@ -672,7 +691,8 @@ public class ResourcesManager { // Rebase each Resources associated with this Activity. final int refCount = activityResources.activityResources.size(); for (int i = 0; i < refCount; i++) { WeakReference<Resources> weakResRef = activityResources.activityResources.get(i); WeakReference<Resources> weakResRef = activityResources.activityResources.get( i); Resources resources = weakResRef.get(); if (resources == null) { continue; Loading @@ -695,15 +715,16 @@ public class ResourcesManager { if (activityHasOverrideConfig && oldKey.hasOverrideConfiguration()) { // Generate a delta between the old base Activity override configuration and // the actual final override configuration that was used to figure out the real // delta this Resources object wanted. // the actual final override configuration that was used to figure out the // real delta this Resources object wanted. Configuration overrideOverrideConfig = Configuration.generateDelta( oldConfig, oldKey.mOverrideConfiguration); rebasedOverrideConfig.updateFrom(overrideOverrideConfig); } // Create the new ResourcesKey with the rebased override config. final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir, oldKey.mSplitResDirs, final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir, oldKey.mSplitResDirs, oldKey.mOverlayDirs, oldKey.mLibDirs, oldKey.mDisplayId, rebasedOverrideConfig, oldKey.mCompatInfo); Loading @@ -719,11 +740,15 @@ public class ResourcesManager { } if (resourcesImpl != resources.getImpl()) { // Set the ResourcesImpl, updating it for all users of this Resources object. // Set the ResourcesImpl, updating it for all users of this Resources // object. resources.setImpl(resourcesImpl); } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /* package */ void setDefaultLocalesLocked(@NonNull LocaleList locales) { Loading @@ -745,6 +770,10 @@ public class ResourcesManager { public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#applyConfigurationToResourcesLocked"); if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq); Loading @@ -768,15 +797,16 @@ public class ResourcesManager { if (!configLocales.isEmpty()) { setDefaultLocalesLocked(configLocales); final LocaleList adjustedLocales = LocaleList.getAdjustedDefault(); if (adjustedLocales != configLocales) { // has the same result as .equals() in this case if (adjustedLocales != configLocales) { // has the same result as .equals() in this case // The first locale in the list was not chosen. So we create a modified // configuration with the adjusted locales (which moves the chosen locale to the // front). localeAdjustedConfig = new Configuration(); localeAdjustedConfig.setTo(config); localeAdjustedConfig.setLocales(adjustedLocales); // Also adjust the locale list in mResConfiguration, so that the Resources created // later would have the same locale list. // Also adjust the locale list in mResConfiguration, so that the Resources // created later would have the same locale list. if (!mResConfiguration.getLocales().equals(adjustedLocales)) { mResConfiguration.setLocales(adjustedLocales); changes |= ActivityInfo.CONFIG_LOCALE; Loading @@ -784,7 +814,8 @@ public class ResourcesManager { } } Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat); Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat); ApplicationPackageManager.configurationChanged(); //Slog.i(TAG, "Configuration changed in " + currentPackageName()); Loading Loading @@ -826,5 +857,8 @@ public class ResourcesManager { } return changes != 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } } libs/androidfw/AssetManager.cpp +3 −14 Original line number Diff line number Diff line Loading @@ -34,9 +34,7 @@ #include <utils/String8.h> #include <utils/threads.h> #include <utils/Timers.h> #ifdef __ANDROID__ #include <cutils/trace.h> #endif #include <utils/Trace.h> #include <assert.h> #include <dirent.h> Loading @@ -54,14 +52,6 @@ _rc; }) #endif #ifdef __ANDROID__ #define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x) #define MY_TRACE_END() ATRACE_END() #else #define MY_TRACE_BEGIN(x) #define MY_TRACE_END() #endif using namespace android; static const bool kIsDebug = false; Loading Loading @@ -623,7 +613,7 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con ResTable* sharedRes = NULL; bool shared = true; bool onlyEmptyResources = true; MY_TRACE_BEGIN(ap.path.string()); ATRACE_NAME(ap.path.string()); Asset* idmap = openIdmapLocked(ap); size_t nextEntryIdx = mResources->getTableCount(); ALOGV("Looking for resource asset in '%s'\n", ap.path.string()); Loading Loading @@ -703,8 +693,6 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con if (idmap != NULL) { delete idmap; } MY_TRACE_END(); return onlyEmptyResources; } Loading Loading @@ -752,6 +740,7 @@ const ResTable* AssetManager::getResTable(bool required) const void AssetManager::updateResourceParamsLocked() const { ATRACE_CALL(); ResTable* res = mResources; if (!res) { return; Loading libs/androidfw/ResourceTypes.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> #include <algorithm> #include <limits> #include <memory> #include <type_traits> Loading Loading @@ -5810,6 +5811,10 @@ const DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) con return NULL; } static bool compareResTableConfig(const ResTable_config& a, const ResTable_config& b) { return a.compare(b) < 0; } void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap, bool ignoreAndroidPackage, bool includeSystemConfigs) const { const size_t packageCount = mPackageGroups.size(); Loading Loading @@ -5840,22 +5845,20 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMi ResTable_config cfg; memset(&cfg, 0, sizeof(ResTable_config)); cfg.copyFromDtoH(config->config); // only insert unique const size_t N = configs->size(); size_t n; for (n = 0; n < N; n++) { if (0 == (*configs)[n].compare(cfg)) { break; } auto iter = std::lower_bound(configs->begin(), configs->end(), cfg, compareResTableConfig); if (iter == configs->end() || iter->compare(cfg) != 0) { configs->insertAt(cfg, std::distance(configs->begin(), iter)); } // if we didn't find it if (n == N) { configs->add(cfg); } } } } } static bool compareString8AndCString(const String8& str, const char* cStr) { return strcmp(str.string(), cStr) < 0; } void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) const Loading @@ -5872,15 +5875,11 @@ void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) c char locale[RESTABLE_MAX_LOCALE_LEN]; for (size_t i=0; i<I; i++) { configs[i].getBcp47Locale(locale); const size_t J = locales->size(); size_t j; for (j=0; j<J; j++) { if (0 == strcmp(locale, (*locales)[j].string())) { break; } } if (j == J) { locales->add(String8(locale)); auto iter = std::lower_bound(locales->begin(), locales->end(), locale, compareString8AndCString); if (iter == locales->end() || strcmp(iter->string(), locale) != 0) { locales->insertAt(String8(locale), std::distance(locales->begin(), iter)); } } } Loading libs/androidfw/tests/ResTable_test.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,20 @@ namespace { */ #include "data/basic/basic_arsc.h" /** * Include a binary library resource table. * * Package: com.android.test.basic */ #include "data/lib/lib_arsc.h" /** * Include a system resource table. * * Package: android */ #include "data/system/system_arsc.h" TEST(ResTableTest, shouldLoadSuccessfully) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); Loading Loading @@ -324,4 +336,25 @@ TEST(ResTableTest, ShareButDontModifyResTable) { ASSERT_EQ(uint32_t(600), val.data); } TEST(ResTableTest, GetConfigurationsReturnsUniqueList) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(system_arsc, system_arsc_len)); ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); ResTable_config configSv; memset(&configSv, 0, sizeof(configSv)); configSv.language[0] = 's'; configSv.language[1] = 'v'; Vector<ResTable_config> configs; table.getConfigurations(&configs); EXPECT_EQ(1, std::count(configs.begin(), configs.end(), configSv)); Vector<String8> locales; table.getLocales(&locales); EXPECT_EQ(1, std::count(locales.begin(), locales.end(), String8("sv"))); } } // namespace libs/androidfw/tests/TestHelpers.h +1 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace android { enum { MAY_NOT_BE_BAG = false }; static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) { return memcmp(&a, &b, sizeof(a)) == 0; return a.compare(b) == 0; } static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) { Loading Loading
core/java/android/app/ResourcesManager.java +217 −183 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.res.ResourcesImpl; import android.content.res.ResourcesKey; import android.hardware.display.DisplayManagerGlobal; import android.os.IBinder; import android.os.Trace; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.LocaleList; Loading Loading @@ -430,6 +431,9 @@ public class ResourcesManager { @Nullable Configuration overrideConfig, @NonNull CompatibilityInfo compatInfo, @Nullable ClassLoader classLoader) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#createBaseActivityResources"); final ResourcesKey key = new ResourcesKey( resDir, splitResDirs, Loading @@ -446,7 +450,8 @@ public class ResourcesManager { } synchronized (this) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); if (overrideConfig != null) { Loading @@ -461,6 +466,9 @@ public class ResourcesManager { // Now request an actual Resources object. return getOrCreateResources(activityToken, key, classLoader); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** Loading Loading @@ -490,8 +498,8 @@ public class ResourcesManager { } if (activityToken != null) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(activityToken); // Clean up any dead references so they don't pile up. ArrayUtils.unstableRemoveIf(activityResources.activityResources, Loading Loading @@ -539,6 +547,7 @@ public class ResourcesManager { final String[] systemLocales = findSystemLocales ? AssetManager.getSystem().getLocales() : null; final String[] nonSystemLocales = resourcesImpl.getAssets().getNonSystemLocales(); // Avoid checking for non-pseudo-locales if we already know there were some from a previous // Resources. The default value (for when hasNonSystemLocales is true) doesn't matter, // since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be Loading Loading @@ -613,6 +622,8 @@ public class ResourcesManager { @Nullable Configuration overrideConfig, @NonNull CompatibilityInfo compatInfo, @Nullable ClassLoader classLoader) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources"); final ResourcesKey key = new ResourcesKey( resDir, splitResDirs, Loading @@ -623,6 +634,9 @@ public class ResourcesManager { compatInfo); classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader(); return getOrCreateResources(activityToken, key, classLoader); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** Loading @@ -636,9 +650,12 @@ public class ResourcesManager { */ public void updateResourcesForActivity(@NonNull IBinder activityToken, @Nullable Configuration overrideConfig) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#updateResourcesForActivity"); synchronized (this) { final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked( activityToken); final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(activityToken); if (Objects.equals(activityResources.overrideConfig, overrideConfig)) { // They are the same, no work to do. Loading @@ -660,9 +677,11 @@ public class ResourcesManager { Throwable here = new Throwable(); here.fillInStackTrace(); Slog.d(TAG, "updating resources override for activity=" + activityToken + " from oldConfig=" + Configuration.resourceQualifierString(oldConfig) + " from oldConfig=" + Configuration.resourceQualifierString(oldConfig) + " to newConfig=" + Configuration.resourceQualifierString(activityResources.overrideConfig), + Configuration.resourceQualifierString( activityResources.overrideConfig), here); } Loading @@ -672,7 +691,8 @@ public class ResourcesManager { // Rebase each Resources associated with this Activity. final int refCount = activityResources.activityResources.size(); for (int i = 0; i < refCount; i++) { WeakReference<Resources> weakResRef = activityResources.activityResources.get(i); WeakReference<Resources> weakResRef = activityResources.activityResources.get( i); Resources resources = weakResRef.get(); if (resources == null) { continue; Loading @@ -695,15 +715,16 @@ public class ResourcesManager { if (activityHasOverrideConfig && oldKey.hasOverrideConfiguration()) { // Generate a delta between the old base Activity override configuration and // the actual final override configuration that was used to figure out the real // delta this Resources object wanted. // the actual final override configuration that was used to figure out the // real delta this Resources object wanted. Configuration overrideOverrideConfig = Configuration.generateDelta( oldConfig, oldKey.mOverrideConfiguration); rebasedOverrideConfig.updateFrom(overrideOverrideConfig); } // Create the new ResourcesKey with the rebased override config. final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir, oldKey.mSplitResDirs, final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir, oldKey.mSplitResDirs, oldKey.mOverlayDirs, oldKey.mLibDirs, oldKey.mDisplayId, rebasedOverrideConfig, oldKey.mCompatInfo); Loading @@ -719,11 +740,15 @@ public class ResourcesManager { } if (resourcesImpl != resources.getImpl()) { // Set the ResourcesImpl, updating it for all users of this Resources object. // Set the ResourcesImpl, updating it for all users of this Resources // object. resources.setImpl(resourcesImpl); } } } } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /* package */ void setDefaultLocalesLocked(@NonNull LocaleList locales) { Loading @@ -745,6 +770,10 @@ public class ResourcesManager { public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#applyConfigurationToResourcesLocked"); if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq); Loading @@ -768,15 +797,16 @@ public class ResourcesManager { if (!configLocales.isEmpty()) { setDefaultLocalesLocked(configLocales); final LocaleList adjustedLocales = LocaleList.getAdjustedDefault(); if (adjustedLocales != configLocales) { // has the same result as .equals() in this case if (adjustedLocales != configLocales) { // has the same result as .equals() in this case // The first locale in the list was not chosen. So we create a modified // configuration with the adjusted locales (which moves the chosen locale to the // front). localeAdjustedConfig = new Configuration(); localeAdjustedConfig.setTo(config); localeAdjustedConfig.setLocales(adjustedLocales); // Also adjust the locale list in mResConfiguration, so that the Resources created // later would have the same locale list. // Also adjust the locale list in mResConfiguration, so that the Resources // created later would have the same locale list. if (!mResConfiguration.getLocales().equals(adjustedLocales)) { mResConfiguration.setLocales(adjustedLocales); changes |= ActivityInfo.CONFIG_LOCALE; Loading @@ -784,7 +814,8 @@ public class ResourcesManager { } } Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat); Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat); ApplicationPackageManager.configurationChanged(); //Slog.i(TAG, "Configuration changed in " + currentPackageName()); Loading Loading @@ -826,5 +857,8 @@ public class ResourcesManager { } return changes != 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } }
libs/androidfw/AssetManager.cpp +3 −14 Original line number Diff line number Diff line Loading @@ -34,9 +34,7 @@ #include <utils/String8.h> #include <utils/threads.h> #include <utils/Timers.h> #ifdef __ANDROID__ #include <cutils/trace.h> #endif #include <utils/Trace.h> #include <assert.h> #include <dirent.h> Loading @@ -54,14 +52,6 @@ _rc; }) #endif #ifdef __ANDROID__ #define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x) #define MY_TRACE_END() ATRACE_END() #else #define MY_TRACE_BEGIN(x) #define MY_TRACE_END() #endif using namespace android; static const bool kIsDebug = false; Loading Loading @@ -623,7 +613,7 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con ResTable* sharedRes = NULL; bool shared = true; bool onlyEmptyResources = true; MY_TRACE_BEGIN(ap.path.string()); ATRACE_NAME(ap.path.string()); Asset* idmap = openIdmapLocked(ap); size_t nextEntryIdx = mResources->getTableCount(); ALOGV("Looking for resource asset in '%s'\n", ap.path.string()); Loading Loading @@ -703,8 +693,6 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con if (idmap != NULL) { delete idmap; } MY_TRACE_END(); return onlyEmptyResources; } Loading Loading @@ -752,6 +740,7 @@ const ResTable* AssetManager::getResTable(bool required) const void AssetManager::updateResourceParamsLocked() const { ATRACE_CALL(); ResTable* res = mResources; if (!res) { return; Loading
libs/androidfw/ResourceTypes.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> #include <algorithm> #include <limits> #include <memory> #include <type_traits> Loading Loading @@ -5810,6 +5811,10 @@ const DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) con return NULL; } static bool compareResTableConfig(const ResTable_config& a, const ResTable_config& b) { return a.compare(b) < 0; } void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap, bool ignoreAndroidPackage, bool includeSystemConfigs) const { const size_t packageCount = mPackageGroups.size(); Loading Loading @@ -5840,22 +5845,20 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMi ResTable_config cfg; memset(&cfg, 0, sizeof(ResTable_config)); cfg.copyFromDtoH(config->config); // only insert unique const size_t N = configs->size(); size_t n; for (n = 0; n < N; n++) { if (0 == (*configs)[n].compare(cfg)) { break; } auto iter = std::lower_bound(configs->begin(), configs->end(), cfg, compareResTableConfig); if (iter == configs->end() || iter->compare(cfg) != 0) { configs->insertAt(cfg, std::distance(configs->begin(), iter)); } // if we didn't find it if (n == N) { configs->add(cfg); } } } } } static bool compareString8AndCString(const String8& str, const char* cStr) { return strcmp(str.string(), cStr) < 0; } void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) const Loading @@ -5872,15 +5875,11 @@ void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) c char locale[RESTABLE_MAX_LOCALE_LEN]; for (size_t i=0; i<I; i++) { configs[i].getBcp47Locale(locale); const size_t J = locales->size(); size_t j; for (j=0; j<J; j++) { if (0 == strcmp(locale, (*locales)[j].string())) { break; } } if (j == J) { locales->add(String8(locale)); auto iter = std::lower_bound(locales->begin(), locales->end(), locale, compareString8AndCString); if (iter == locales->end() || strcmp(iter->string(), locale) != 0) { locales->insertAt(String8(locale), std::distance(locales->begin(), iter)); } } } Loading
libs/androidfw/tests/ResTable_test.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,20 @@ namespace { */ #include "data/basic/basic_arsc.h" /** * Include a binary library resource table. * * Package: com.android.test.basic */ #include "data/lib/lib_arsc.h" /** * Include a system resource table. * * Package: android */ #include "data/system/system_arsc.h" TEST(ResTableTest, shouldLoadSuccessfully) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); Loading Loading @@ -324,4 +336,25 @@ TEST(ResTableTest, ShareButDontModifyResTable) { ASSERT_EQ(uint32_t(600), val.data); } TEST(ResTableTest, GetConfigurationsReturnsUniqueList) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(system_arsc, system_arsc_len)); ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); ResTable_config configSv; memset(&configSv, 0, sizeof(configSv)); configSv.language[0] = 's'; configSv.language[1] = 'v'; Vector<ResTable_config> configs; table.getConfigurations(&configs); EXPECT_EQ(1, std::count(configs.begin(), configs.end(), configSv)); Vector<String8> locales; table.getLocales(&locales); EXPECT_EQ(1, std::count(locales.begin(), locales.end(), String8("sv"))); } } // namespace
libs/androidfw/tests/TestHelpers.h +1 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace android { enum { MAY_NOT_BE_BAG = false }; static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) { return memcmp(&a, &b, sizeof(a)) == 0; return a.compare(b) == 0; } static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) { Loading