Merge "Merge commit 'fb96e54' into manualmerge" into lmp-mr1-dev-plus-aosp
This commit is contained in:
committed by
Android (Google) Code Review
commit
8491c4ead7
@@ -3645,8 +3645,12 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
|
|||||||
Entry entry;
|
Entry entry;
|
||||||
status_t err = getEntry(grp, t, e, &desiredConfig, &entry);
|
status_t err = getEntry(grp, t, e, &desiredConfig, &entry);
|
||||||
if (err != NO_ERROR) {
|
if (err != NO_ERROR) {
|
||||||
|
// Only log the failure when we're not running on the host as
|
||||||
|
// part of a tool. The caller will do its own logging.
|
||||||
|
#ifndef STATIC_ANDROIDFW_FOR_TOOLS
|
||||||
ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n",
|
ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n",
|
||||||
resID, t, e, err);
|
resID, t, e, err);
|
||||||
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -794,4 +794,23 @@ bool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMa
|
|||||||
return a.diff(b) == axisMask;
|
return a.diff(b) == axisMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDensityOnly(const ResTable_config& config) {
|
||||||
|
if (config.density == ResTable_config::DENSITY_NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.density == ResTable_config::DENSITY_ANY) {
|
||||||
|
if (config.sdkVersion != SDK_L) {
|
||||||
|
// Someone modified the sdkVersion from the default, this is not safe to assume.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (config.sdkVersion != SDK_DONUT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;
|
||||||
|
const ConfigDescription nullConfig;
|
||||||
|
return (nullConfig.diff(config) & ~mask) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace AaptConfig
|
} // namespace AaptConfig
|
||||||
|
|||||||
@@ -80,6 +80,12 @@ android::String8 getVersion(const android::ResTable_config& config);
|
|||||||
*/
|
*/
|
||||||
bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);
|
bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the configuration only has the density specified. In the case
|
||||||
|
* of 'anydpi', the version is ignored.
|
||||||
|
*/
|
||||||
|
bool isDensityOnly(const android::ResTable_config& config);
|
||||||
|
|
||||||
} // namespace AaptConfig
|
} // namespace AaptConfig
|
||||||
|
|
||||||
#endif // __AAPT_CONFIG_H
|
#endif // __AAPT_CONFIG_H
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// Build resource files from raw assets.
|
// Build resource files from raw assets.
|
||||||
//
|
//
|
||||||
#include "AaptAssets.h"
|
#include "AaptAssets.h"
|
||||||
|
#include "AaptUtil.h"
|
||||||
#include "AaptXml.h"
|
#include "AaptXml.h"
|
||||||
#include "CacheUpdater.h"
|
#include "CacheUpdater.h"
|
||||||
#include "CrunchCache.h"
|
#include "CrunchCache.h"
|
||||||
@@ -13,10 +14,14 @@
|
|||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
#include "ResourceTable.h"
|
#include "ResourceTable.h"
|
||||||
#include "StringPool.h"
|
#include "StringPool.h"
|
||||||
|
#include "Symbol.h"
|
||||||
#include "WorkQueue.h"
|
#include "WorkQueue.h"
|
||||||
#include "XMLNode.h"
|
#include "XMLNode.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
|
// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.
|
||||||
|
|
||||||
#if HAVE_PRINTF_ZD
|
#if HAVE_PRINTF_ZD
|
||||||
# define ZD "%zd"
|
# define ZD "%zd"
|
||||||
# define ZD_TYPE ssize_t
|
# define ZD_TYPE ssize_t
|
||||||
@@ -1580,6 +1585,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
|||||||
// Re-flatten because we may have added new resource IDs
|
// Re-flatten because we may have added new resource IDs
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
ResTable finalResTable;
|
ResTable finalResTable;
|
||||||
sp<AaptFile> resFile;
|
sp<AaptFile> resFile;
|
||||||
|
|
||||||
@@ -1590,6 +1596,13 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;
|
||||||
|
if (builder->getSplits().size() > 1) {
|
||||||
|
// Only look for density varying resources if we're generating
|
||||||
|
// splits.
|
||||||
|
table.getDensityVaryingResources(densityVaryingResources);
|
||||||
|
}
|
||||||
|
|
||||||
Vector<sp<ApkSplit> >& splits = builder->getSplits();
|
Vector<sp<ApkSplit> >& splits = builder->getSplits();
|
||||||
const size_t numSplits = splits.size();
|
const size_t numSplits = splits.size();
|
||||||
for (size_t i = 0; i < numSplits; i++) {
|
for (size_t i = 0; i < numSplits; i++) {
|
||||||
@@ -1613,6 +1626,63 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
ResTable resTable;
|
||||||
|
err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
|
||||||
|
if (err != NO_ERROR) {
|
||||||
|
fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
|
||||||
|
split->getPrintableName().string());
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasError = false;
|
||||||
|
const std::set<ConfigDescription>& splitConfigs = split->getConfigs();
|
||||||
|
for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();
|
||||||
|
iter != splitConfigs.end();
|
||||||
|
++iter) {
|
||||||
|
const ConfigDescription& config = *iter;
|
||||||
|
if (AaptConfig::isDensityOnly(config)) {
|
||||||
|
// Each density only split must contain all
|
||||||
|
// density only resources.
|
||||||
|
Res_value val;
|
||||||
|
resTable.setParameters(&config);
|
||||||
|
const size_t densityVaryingResourceCount = densityVaryingResources.size();
|
||||||
|
for (size_t k = 0; k < densityVaryingResourceCount; k++) {
|
||||||
|
const Symbol& symbol = densityVaryingResources.keyAt(k);
|
||||||
|
ssize_t block = resTable.getResource(symbol.id, &val, true);
|
||||||
|
if (block < 0) {
|
||||||
|
// Maybe it's in the base?
|
||||||
|
finalResTable.setParameters(&config);
|
||||||
|
block = finalResTable.getResource(symbol.id, &val, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block < 0) {
|
||||||
|
hasError = true;
|
||||||
|
SourcePos().error("%s has no definition for density split '%s'",
|
||||||
|
symbol.toString().string(), config.toString().string());
|
||||||
|
|
||||||
|
if (bundle->getVerbose()) {
|
||||||
|
const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
|
||||||
|
const size_t defCount = std::min(size_t(5), defs.size());
|
||||||
|
for (size_t d = 0; d < defCount; d++) {
|
||||||
|
const SymbolDefinition& def = defs[d];
|
||||||
|
def.source.error("%s has definition for %s",
|
||||||
|
symbol.toString().string(), def.config.toString().string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defCount < defs.size()) {
|
||||||
|
SourcePos().error("and %d more ...", (int) (defs.size() - defCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the AndroidManifest for this split.
|
||||||
sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
|
sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
|
||||||
AaptGroupEntry(), String8());
|
AaptGroupEntry(), String8());
|
||||||
err = generateAndroidManifestForSplit(bundle, assets, split,
|
err = generateAndroidManifestForSplit(bundle, assets, split,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "ResourceTable.h"
|
#include "ResourceTable.h"
|
||||||
|
|
||||||
|
#include "AaptUtil.h"
|
||||||
#include "XMLNode.h"
|
#include "XMLNode.h"
|
||||||
#include "ResourceFilter.h"
|
#include "ResourceFilter.h"
|
||||||
#include "ResourceIdCache.h"
|
#include "ResourceIdCache.h"
|
||||||
@@ -4517,3 +4518,34 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,
|
|||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
|
||||||
|
const ConfigDescription nullConfig;
|
||||||
|
|
||||||
|
const size_t packageCount = mOrderedPackages.size();
|
||||||
|
for (size_t p = 0; p < packageCount; p++) {
|
||||||
|
const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes();
|
||||||
|
const size_t typeCount = types.size();
|
||||||
|
for (size_t t = 0; t < typeCount; t++) {
|
||||||
|
const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs();
|
||||||
|
const size_t configCount = configs.size();
|
||||||
|
for (size_t c = 0; c < configCount; c++) {
|
||||||
|
const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries();
|
||||||
|
const size_t configEntryCount = configEntries.size();
|
||||||
|
for (size_t ce = 0; ce < configEntryCount; ce++) {
|
||||||
|
const ConfigDescription& config = configEntries.keyAt(ce);
|
||||||
|
if (AaptConfig::isDensityOnly(config)) {
|
||||||
|
// This configuration only varies with regards to density.
|
||||||
|
const Symbol symbol(mOrderedPackages[p]->getName(),
|
||||||
|
types[t]->getName(),
|
||||||
|
configs[c]->getName(),
|
||||||
|
getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex()));
|
||||||
|
|
||||||
|
const sp<Entry>& entry = configEntries.valueAt(ce);
|
||||||
|
AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,15 +7,16 @@
|
|||||||
#ifndef RESOURCE_TABLE_H
|
#ifndef RESOURCE_TABLE_H
|
||||||
#define RESOURCE_TABLE_H
|
#define RESOURCE_TABLE_H
|
||||||
|
|
||||||
#include "ConfigDescription.h"
|
|
||||||
#include "StringPool.h"
|
|
||||||
#include "SourcePos.h"
|
|
||||||
#include "ResourceFilter.h"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "ConfigDescription.h"
|
||||||
|
#include "ResourceFilter.h"
|
||||||
|
#include "SourcePos.h"
|
||||||
|
#include "StringPool.h"
|
||||||
|
#include "Symbol.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
@@ -543,6 +544,8 @@ public:
|
|||||||
DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
|
DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
|
void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
|
||||||
sp<Package> getPackage(const String16& package);
|
sp<Package> getPackage(const String16& package);
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ SourcePos::printf(const char* fmt, ...) const
|
|||||||
ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);
|
ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourcePos::operator<(const SourcePos& rhs) const
|
||||||
|
{
|
||||||
|
return (file < rhs.file) || (line < rhs.line);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SourcePos::hasErrors()
|
SourcePos::hasErrors()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ public:
|
|||||||
void warning(const char* fmt, ...) const;
|
void warning(const char* fmt, ...) const;
|
||||||
void printf(const char* fmt, ...) const;
|
void printf(const char* fmt, ...) const;
|
||||||
|
|
||||||
|
bool operator<(const SourcePos& rhs) const;
|
||||||
|
|
||||||
static bool hasErrors();
|
static bool hasErrors();
|
||||||
static void printErrors(FILE* to);
|
static void printErrors(FILE* to);
|
||||||
};
|
};
|
||||||
|
|||||||
95
tools/aapt/Symbol.h
Normal file
95
tools/aapt/Symbol.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AAPT_SYMBOL_H
|
||||||
|
#define AAPT_SYMBOL_H
|
||||||
|
|
||||||
|
#include <utils/String8.h>
|
||||||
|
#include <utils/String16.h>
|
||||||
|
|
||||||
|
#include "ConfigDescription.h"
|
||||||
|
#include "SourcePos.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A resource symbol, not attached to any configuration or context.
|
||||||
|
*/
|
||||||
|
struct Symbol {
|
||||||
|
inline Symbol();
|
||||||
|
inline Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i);
|
||||||
|
inline android::String8 toString() const;
|
||||||
|
inline bool operator<(const Symbol& rhs) const;
|
||||||
|
|
||||||
|
android::String16 package;
|
||||||
|
android::String16 type;
|
||||||
|
android::String16 name;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specific defintion of a symbol, defined with a configuration and a definition site.
|
||||||
|
*/
|
||||||
|
struct SymbolDefinition {
|
||||||
|
inline SymbolDefinition();
|
||||||
|
inline SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src);
|
||||||
|
inline bool operator<(const SymbolDefinition& rhs) const;
|
||||||
|
|
||||||
|
Symbol symbol;
|
||||||
|
ConfigDescription config;
|
||||||
|
SourcePos source;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementations
|
||||||
|
//
|
||||||
|
|
||||||
|
Symbol::Symbol() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol::Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i)
|
||||||
|
: package(p)
|
||||||
|
, type(t)
|
||||||
|
, name(n)
|
||||||
|
, id(i) {
|
||||||
|
}
|
||||||
|
|
||||||
|
android::String8 Symbol::toString() const {
|
||||||
|
return android::String8::format("%s:%s/%s (0x%08x)",
|
||||||
|
android::String8(package).string(),
|
||||||
|
android::String8(type).string(),
|
||||||
|
android::String8(name).string(),
|
||||||
|
(int) id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Symbol::operator<(const Symbol& rhs) const {
|
||||||
|
return (package < rhs.package) || (type < rhs.type) || (name < rhs.name) || (id < rhs.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolDefinition::SymbolDefinition() {
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolDefinition::SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src)
|
||||||
|
: symbol(s)
|
||||||
|
, config(c)
|
||||||
|
, source(src) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SymbolDefinition::operator<(const SymbolDefinition& rhs) const {
|
||||||
|
return (symbol < rhs.symbol) || (config < rhs.config) || (source < rhs.source);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // AAPT_SYMBOL_H
|
||||||
|
|
||||||
Reference in New Issue
Block a user