Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af2758a9 authored by Adam Lesinski's avatar Adam Lesinski Committed by android-build-merger
Browse files

Merge "Optimize ResTable::getLocales() to improve bindApplication performance" into nyc-dev

am: bfdc2020

* commit 'bfdc2020':
  Optimize ResTable::getLocales() to improve bindApplication performance

Change-Id: I5148dabc722ec2c31008ba05adb3ccdfa357857a
parents 06c88414 bfdc2020
Loading
Loading
Loading
Loading
+217 −183
Original line number Diff line number Diff line
@@ -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;
@@ -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,
@@ -446,7 +450,8 @@ public class ResourcesManager {
            }

            synchronized (this) {
            final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
                final ActivityResources activityResources =
                        getOrCreateActivityResourcesStructLocked(
                                activityToken);

                if (overrideConfig != null) {
@@ -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);
        }
    }

    /**
@@ -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,
@@ -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
@@ -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,
@@ -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);
        }
    }

    /**
@@ -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.
@@ -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);
                }

@@ -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;
@@ -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);

@@ -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) {
@@ -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);
@@ -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;
@@ -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());
@@ -826,5 +857,8 @@ public class ResourcesManager {
            }

            return changes != 0;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
    }
}
+3 −14
Original line number Diff line number Diff line
@@ -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>
@@ -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;
@@ -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());
@@ -703,8 +693,6 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con
    if (idmap != NULL) {
        delete idmap;
    }
    MY_TRACE_END();

    return onlyEmptyResources;
}

@@ -752,6 +740,7 @@ const ResTable* AssetManager::getResTable(bool required) const

void AssetManager::updateResourceParamsLocked() const
{
    ATRACE_CALL();
    ResTable* res = mResources;
    if (!res) {
        return;
+19 −20
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <type_traits>
@@ -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();
@@ -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
@@ -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));
        }
    }
}
+33 −0
Original line number Diff line number Diff line
@@ -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));
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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