Merge "Optimize ResTable::getLocales() to improve bindApplication performance" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
bfdc2020b9
@@ -29,6 +29,7 @@ import android.content.res.ResourcesImpl;
|
|||||||
import android.content.res.ResourcesKey;
|
import android.content.res.ResourcesKey;
|
||||||
import android.hardware.display.DisplayManagerGlobal;
|
import android.hardware.display.DisplayManagerGlobal;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Trace;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.LocaleList;
|
import android.util.LocaleList;
|
||||||
@@ -430,6 +431,9 @@ public class ResourcesManager {
|
|||||||
@Nullable Configuration overrideConfig,
|
@Nullable Configuration overrideConfig,
|
||||||
@NonNull CompatibilityInfo compatInfo,
|
@NonNull CompatibilityInfo compatInfo,
|
||||||
@Nullable ClassLoader classLoader) {
|
@Nullable ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
|
||||||
|
"ResourcesManager#createBaseActivityResources");
|
||||||
final ResourcesKey key = new ResourcesKey(
|
final ResourcesKey key = new ResourcesKey(
|
||||||
resDir,
|
resDir,
|
||||||
splitResDirs,
|
splitResDirs,
|
||||||
@@ -446,7 +450,8 @@ public class ResourcesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
|
final ActivityResources activityResources =
|
||||||
|
getOrCreateActivityResourcesStructLocked(
|
||||||
activityToken);
|
activityToken);
|
||||||
|
|
||||||
if (overrideConfig != null) {
|
if (overrideConfig != null) {
|
||||||
@@ -461,6 +466,9 @@ public class ResourcesManager {
|
|||||||
|
|
||||||
// Now request an actual Resources object.
|
// Now request an actual Resources object.
|
||||||
return getOrCreateResources(activityToken, key, classLoader);
|
return getOrCreateResources(activityToken, key, classLoader);
|
||||||
|
} finally {
|
||||||
|
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -490,8 +498,8 @@ public class ResourcesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activityToken != null) {
|
if (activityToken != null) {
|
||||||
final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
|
final ActivityResources activityResources =
|
||||||
activityToken);
|
getOrCreateActivityResourcesStructLocked(activityToken);
|
||||||
|
|
||||||
// Clean up any dead references so they don't pile up.
|
// Clean up any dead references so they don't pile up.
|
||||||
ArrayUtils.unstableRemoveIf(activityResources.activityResources,
|
ArrayUtils.unstableRemoveIf(activityResources.activityResources,
|
||||||
@@ -539,6 +547,7 @@ public class ResourcesManager {
|
|||||||
final String[] systemLocales = findSystemLocales
|
final String[] systemLocales = findSystemLocales
|
||||||
? AssetManager.getSystem().getLocales() : null;
|
? AssetManager.getSystem().getLocales() : null;
|
||||||
final String[] nonSystemLocales = resourcesImpl.getAssets().getNonSystemLocales();
|
final String[] nonSystemLocales = resourcesImpl.getAssets().getNonSystemLocales();
|
||||||
|
|
||||||
// Avoid checking for non-pseudo-locales if we already know there were some from a previous
|
// 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,
|
// Resources. The default value (for when hasNonSystemLocales is true) doesn't matter,
|
||||||
// since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be
|
// since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be
|
||||||
@@ -613,6 +622,8 @@ public class ResourcesManager {
|
|||||||
@Nullable Configuration overrideConfig,
|
@Nullable Configuration overrideConfig,
|
||||||
@NonNull CompatibilityInfo compatInfo,
|
@NonNull CompatibilityInfo compatInfo,
|
||||||
@Nullable ClassLoader classLoader) {
|
@Nullable ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources");
|
||||||
final ResourcesKey key = new ResourcesKey(
|
final ResourcesKey key = new ResourcesKey(
|
||||||
resDir,
|
resDir,
|
||||||
splitResDirs,
|
splitResDirs,
|
||||||
@@ -623,6 +634,9 @@ public class ResourcesManager {
|
|||||||
compatInfo);
|
compatInfo);
|
||||||
classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
|
classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
|
||||||
return getOrCreateResources(activityToken, key, classLoader);
|
return getOrCreateResources(activityToken, key, classLoader);
|
||||||
|
} finally {
|
||||||
|
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -636,9 +650,12 @@ public class ResourcesManager {
|
|||||||
*/
|
*/
|
||||||
public void updateResourcesForActivity(@NonNull IBinder activityToken,
|
public void updateResourcesForActivity(@NonNull IBinder activityToken,
|
||||||
@Nullable Configuration overrideConfig) {
|
@Nullable Configuration overrideConfig) {
|
||||||
|
try {
|
||||||
|
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
|
||||||
|
"ResourcesManager#updateResourcesForActivity");
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
|
final ActivityResources activityResources =
|
||||||
activityToken);
|
getOrCreateActivityResourcesStructLocked(activityToken);
|
||||||
|
|
||||||
if (Objects.equals(activityResources.overrideConfig, overrideConfig)) {
|
if (Objects.equals(activityResources.overrideConfig, overrideConfig)) {
|
||||||
// They are the same, no work to do.
|
// They are the same, no work to do.
|
||||||
@@ -660,9 +677,11 @@ public class ResourcesManager {
|
|||||||
Throwable here = new Throwable();
|
Throwable here = new Throwable();
|
||||||
here.fillInStackTrace();
|
here.fillInStackTrace();
|
||||||
Slog.d(TAG, "updating resources override for activity=" + activityToken
|
Slog.d(TAG, "updating resources override for activity=" + activityToken
|
||||||
+ " from oldConfig=" + Configuration.resourceQualifierString(oldConfig)
|
+ " from oldConfig="
|
||||||
|
+ Configuration.resourceQualifierString(oldConfig)
|
||||||
+ " to newConfig="
|
+ " to newConfig="
|
||||||
+ Configuration.resourceQualifierString(activityResources.overrideConfig),
|
+ Configuration.resourceQualifierString(
|
||||||
|
activityResources.overrideConfig),
|
||||||
here);
|
here);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +691,8 @@ public class ResourcesManager {
|
|||||||
// Rebase each Resources associated with this Activity.
|
// Rebase each Resources associated with this Activity.
|
||||||
final int refCount = activityResources.activityResources.size();
|
final int refCount = activityResources.activityResources.size();
|
||||||
for (int i = 0; i < refCount; i++) {
|
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();
|
Resources resources = weakResRef.get();
|
||||||
if (resources == null) {
|
if (resources == null) {
|
||||||
continue;
|
continue;
|
||||||
@@ -695,15 +715,16 @@ public class ResourcesManager {
|
|||||||
|
|
||||||
if (activityHasOverrideConfig && oldKey.hasOverrideConfiguration()) {
|
if (activityHasOverrideConfig && oldKey.hasOverrideConfiguration()) {
|
||||||
// Generate a delta between the old base Activity override configuration and
|
// Generate a delta between the old base Activity override configuration and
|
||||||
// the actual final override configuration that was used to figure out the real
|
// the actual final override configuration that was used to figure out the
|
||||||
// delta this Resources object wanted.
|
// real delta this Resources object wanted.
|
||||||
Configuration overrideOverrideConfig = Configuration.generateDelta(
|
Configuration overrideOverrideConfig = Configuration.generateDelta(
|
||||||
oldConfig, oldKey.mOverrideConfiguration);
|
oldConfig, oldKey.mOverrideConfiguration);
|
||||||
rebasedOverrideConfig.updateFrom(overrideOverrideConfig);
|
rebasedOverrideConfig.updateFrom(overrideOverrideConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new ResourcesKey with the rebased override config.
|
// 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,
|
oldKey.mOverlayDirs, oldKey.mLibDirs, oldKey.mDisplayId,
|
||||||
rebasedOverrideConfig, oldKey.mCompatInfo);
|
rebasedOverrideConfig, oldKey.mCompatInfo);
|
||||||
|
|
||||||
@@ -719,11 +740,15 @@ public class ResourcesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resourcesImpl != resources.getImpl()) {
|
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);
|
resources.setImpl(resourcesImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void setDefaultLocalesLocked(@NonNull LocaleList locales) {
|
/* package */ void setDefaultLocalesLocked(@NonNull LocaleList locales) {
|
||||||
@@ -745,6 +770,10 @@ public class ResourcesManager {
|
|||||||
|
|
||||||
public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
|
public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
|
||||||
@Nullable CompatibilityInfo compat) {
|
@Nullable CompatibilityInfo compat) {
|
||||||
|
try {
|
||||||
|
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
|
||||||
|
"ResourcesManager#applyConfigurationToResourcesLocked");
|
||||||
|
|
||||||
if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
|
if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
|
||||||
if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
|
if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
|
||||||
+ mResConfiguration.seq + ", newSeq=" + config.seq);
|
+ mResConfiguration.seq + ", newSeq=" + config.seq);
|
||||||
@@ -768,15 +797,16 @@ public class ResourcesManager {
|
|||||||
if (!configLocales.isEmpty()) {
|
if (!configLocales.isEmpty()) {
|
||||||
setDefaultLocalesLocked(configLocales);
|
setDefaultLocalesLocked(configLocales);
|
||||||
final LocaleList adjustedLocales = LocaleList.getAdjustedDefault();
|
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
|
// 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
|
// configuration with the adjusted locales (which moves the chosen locale to the
|
||||||
// front).
|
// front).
|
||||||
localeAdjustedConfig = new Configuration();
|
localeAdjustedConfig = new Configuration();
|
||||||
localeAdjustedConfig.setTo(config);
|
localeAdjustedConfig.setTo(config);
|
||||||
localeAdjustedConfig.setLocales(adjustedLocales);
|
localeAdjustedConfig.setLocales(adjustedLocales);
|
||||||
// Also adjust the locale list in mResConfiguration, so that the Resources created
|
// Also adjust the locale list in mResConfiguration, so that the Resources
|
||||||
// later would have the same locale list.
|
// created later would have the same locale list.
|
||||||
if (!mResConfiguration.getLocales().equals(adjustedLocales)) {
|
if (!mResConfiguration.getLocales().equals(adjustedLocales)) {
|
||||||
mResConfiguration.setLocales(adjustedLocales);
|
mResConfiguration.setLocales(adjustedLocales);
|
||||||
changes |= ActivityInfo.CONFIG_LOCALE;
|
changes |= ActivityInfo.CONFIG_LOCALE;
|
||||||
@@ -784,7 +814,8 @@ public class ResourcesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat);
|
Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics,
|
||||||
|
compat);
|
||||||
|
|
||||||
ApplicationPackageManager.configurationChanged();
|
ApplicationPackageManager.configurationChanged();
|
||||||
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
|
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
|
||||||
@@ -826,5 +857,8 @@ public class ResourcesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return changes != 0;
|
return changes != 0;
|
||||||
|
} finally {
|
||||||
|
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,7 @@
|
|||||||
#include <utils/String8.h>
|
#include <utils/String8.h>
|
||||||
#include <utils/threads.h>
|
#include <utils/threads.h>
|
||||||
#include <utils/Timers.h>
|
#include <utils/Timers.h>
|
||||||
#ifdef __ANDROID__
|
#include <utils/Trace.h>
|
||||||
#include <cutils/trace.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@@ -54,14 +52,6 @@
|
|||||||
_rc; })
|
_rc; })
|
||||||
#endif
|
#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;
|
using namespace android;
|
||||||
|
|
||||||
static const bool kIsDebug = false;
|
static const bool kIsDebug = false;
|
||||||
@@ -623,7 +613,7 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con
|
|||||||
ResTable* sharedRes = NULL;
|
ResTable* sharedRes = NULL;
|
||||||
bool shared = true;
|
bool shared = true;
|
||||||
bool onlyEmptyResources = true;
|
bool onlyEmptyResources = true;
|
||||||
MY_TRACE_BEGIN(ap.path.string());
|
ATRACE_NAME(ap.path.string());
|
||||||
Asset* idmap = openIdmapLocked(ap);
|
Asset* idmap = openIdmapLocked(ap);
|
||||||
size_t nextEntryIdx = mResources->getTableCount();
|
size_t nextEntryIdx = mResources->getTableCount();
|
||||||
ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
|
ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
|
||||||
@@ -703,8 +693,6 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con
|
|||||||
if (idmap != NULL) {
|
if (idmap != NULL) {
|
||||||
delete idmap;
|
delete idmap;
|
||||||
}
|
}
|
||||||
MY_TRACE_END();
|
|
||||||
|
|
||||||
return onlyEmptyResources;
|
return onlyEmptyResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,6 +740,7 @@ const ResTable* AssetManager::getResTable(bool required) const
|
|||||||
|
|
||||||
void AssetManager::updateResourceParamsLocked() const
|
void AssetManager::updateResourceParamsLocked() const
|
||||||
{
|
{
|
||||||
|
ATRACE_CALL();
|
||||||
ResTable* res = mResources;
|
ResTable* res = mResources;
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -5810,6 +5811,10 @@ const DynamicRefTable* ResTable::getDynamicRefTableForCookie(int32_t cookie) con
|
|||||||
return NULL;
|
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,
|
void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMipmap,
|
||||||
bool ignoreAndroidPackage, bool includeSystemConfigs) const {
|
bool ignoreAndroidPackage, bool includeSystemConfigs) const {
|
||||||
const size_t packageCount = mPackageGroups.size();
|
const size_t packageCount = mPackageGroups.size();
|
||||||
@@ -5840,17 +5845,11 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMi
|
|||||||
ResTable_config cfg;
|
ResTable_config cfg;
|
||||||
memset(&cfg, 0, sizeof(ResTable_config));
|
memset(&cfg, 0, sizeof(ResTable_config));
|
||||||
cfg.copyFromDtoH(config->config);
|
cfg.copyFromDtoH(config->config);
|
||||||
// only insert unique
|
|
||||||
const size_t N = configs->size();
|
auto iter = std::lower_bound(configs->begin(), configs->end(), cfg,
|
||||||
size_t n;
|
compareResTableConfig);
|
||||||
for (n = 0; n < N; n++) {
|
if (iter == configs->end() || iter->compare(cfg) != 0) {
|
||||||
if (0 == (*configs)[n].compare(cfg)) {
|
configs->insertAt(cfg, std::distance(configs->begin(), iter));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we didn't find it
|
|
||||||
if (n == N) {
|
|
||||||
configs->add(cfg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5858,6 +5857,10 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs, bool ignoreMi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compareString8AndCString(const String8& str, const char* cStr) {
|
||||||
|
return strcmp(str.string(), cStr) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) const
|
void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) const
|
||||||
{
|
{
|
||||||
Vector<ResTable_config> configs;
|
Vector<ResTable_config> configs;
|
||||||
@@ -5872,15 +5875,11 @@ void ResTable::getLocales(Vector<String8>* locales, bool includeSystemLocales) c
|
|||||||
char locale[RESTABLE_MAX_LOCALE_LEN];
|
char locale[RESTABLE_MAX_LOCALE_LEN];
|
||||||
for (size_t i=0; i<I; i++) {
|
for (size_t i=0; i<I; i++) {
|
||||||
configs[i].getBcp47Locale(locale);
|
configs[i].getBcp47Locale(locale);
|
||||||
const size_t J = locales->size();
|
|
||||||
size_t j;
|
auto iter = std::lower_bound(locales->begin(), locales->end(), locale,
|
||||||
for (j=0; j<J; j++) {
|
compareString8AndCString);
|
||||||
if (0 == strcmp(locale, (*locales)[j].string())) {
|
if (iter == locales->end() || strcmp(iter->string(), locale) != 0) {
|
||||||
break;
|
locales->insertAt(String8(locale), std::distance(locales->begin(), iter));
|
||||||
}
|
|
||||||
}
|
|
||||||
if (j == J) {
|
|
||||||
locales->add(String8(locale));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,20 @@ namespace {
|
|||||||
*/
|
*/
|
||||||
#include "data/basic/basic_arsc.h"
|
#include "data/basic/basic_arsc.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include a binary library resource table.
|
||||||
|
*
|
||||||
|
* Package: com.android.test.basic
|
||||||
|
*/
|
||||||
#include "data/lib/lib_arsc.h"
|
#include "data/lib/lib_arsc.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include a system resource table.
|
||||||
|
*
|
||||||
|
* Package: android
|
||||||
|
*/
|
||||||
|
#include "data/system/system_arsc.h"
|
||||||
|
|
||||||
TEST(ResTableTest, shouldLoadSuccessfully) {
|
TEST(ResTableTest, shouldLoadSuccessfully) {
|
||||||
ResTable table;
|
ResTable table;
|
||||||
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
|
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
|
||||||
@@ -324,4 +336,25 @@ TEST(ResTableTest, ShareButDontModifyResTable) {
|
|||||||
ASSERT_EQ(uint32_t(600), val.data);
|
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
|
} // namespace
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace android {
|
|||||||
enum { MAY_NOT_BE_BAG = false };
|
enum { MAY_NOT_BE_BAG = false };
|
||||||
|
|
||||||
static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) {
|
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) {
|
static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ namespace style {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace integer {
|
||||||
|
enum {
|
||||||
|
number = 0x01030000, // sv
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace R
|
} // namespace R
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|||||||
20
libs/androidfw/tests/data/system/res/values-sv/values.xml
Normal file
20
libs/androidfw/tests/data/system/res/values-sv/values.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<public type="integer" name="number" id="0x01030000" />
|
||||||
|
<integer name="number">1</integer>
|
||||||
|
</resources>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
unsigned char system_arsc[] = {
|
unsigned char system_arsc[] = {
|
||||||
0x02, 0x00, 0x0c, 0x00, 0x18, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
0x02, 0x00, 0x0c, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf0, 0x02, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xd0, 0x03, 0x00, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00,
|
||||||
0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -25,26 +25,33 @@ unsigned char system_arsc[] = {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
|
||||||
0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
0x04, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,
|
0x0c, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
|
||||||
0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,
|
0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00,
|
||||||
0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,
|
0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00,
|
||||||
0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x5e, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x2d, 0x00, 0x70, 0x00,
|
||||||
|
0x72, 0x00, 0x69, 0x00, 0x76, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x84, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
|
||||||
0x0a, 0x00, 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x67, 0x00,
|
0x0a, 0x00, 0x62, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x67, 0x00,
|
||||||
0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,
|
0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,
|
||||||
0x0a, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x67, 0x00,
|
0x0a, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x67, 0x00,
|
||||||
0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,
|
0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x00, 0x00,
|
||||||
0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,
|
0x09, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00,
|
||||||
0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x2e, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||||
0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00,
|
||||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||||
0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
|
||||||
0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x4c, 0x00, 0x8c, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -55,15 +62,27 @@ unsigned char system_arsc[] = {
|
|||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00,
|
||||||
0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x44, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x4c, 0x00,
|
||||||
0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
0x78, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x50, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0xff, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||||
0x01, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xff
|
0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x01, 0x01,
|
||||||
|
0x08, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xff, 0x02, 0x02, 0x10, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x40, 0x01, 0x02, 0x4c, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
unsigned int system_arsc_len = 792;
|
unsigned int system_arsc_len = 1016;
|
||||||
|
|||||||
Reference in New Issue
Block a user