diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-09-16 14:43:29 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2014-10-23 10:39:31 -0700 |
commit | 40e8eefbedcafc51948945647d746daaee092f16 (patch) | |
tree | eb14bacf3510fc8865145a1c68b4dcb8fc802904 /tools/split-select/SplitDescription.cpp | |
parent | 74af6700196ed55a0aa39c7777293e735e7b4d73 (diff) | |
download | frameworks_base-40e8eefbedcafc51948945647d746daaee092f16.zip frameworks_base-40e8eefbedcafc51948945647d746daaee092f16.tar.gz frameworks_base-40e8eefbedcafc51948945647d746daaee092f16.tar.bz2 |
First commit of split-select tool
This tool emits a set of rules as JSON for when a Split APK
should match a target device.
Change-Id: I8bfbdfbdb51efcfc645889dd03e1961f16e39645
Diffstat (limited to 'tools/split-select/SplitDescription.cpp')
-rw-r--r-- | tools/split-select/SplitDescription.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/tools/split-select/SplitDescription.cpp b/tools/split-select/SplitDescription.cpp new file mode 100644 index 0000000..8037ef0 --- /dev/null +++ b/tools/split-select/SplitDescription.cpp @@ -0,0 +1,175 @@ +/* + * 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. + */ + +#include "SplitDescription.h" + +#include "aapt/AaptConfig.h" +#include "aapt/AaptUtil.h" + +#include <utils/String8.h> +#include <utils/Vector.h> + +using namespace android; + +namespace split { + +SplitDescription::SplitDescription() +: abi(abi::Variant::none) { +} + +int SplitDescription::compare(const SplitDescription& rhs) const { + int cmp; + cmp = (int)abi - (int)rhs.abi; + if (cmp != 0) return cmp; + return config.compareLogical(rhs.config); +} + +bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescription& target) const { + if (abi != abi::Variant::none || o.abi != abi::Variant::none) { + abi::Family family = abi::getFamily(abi); + abi::Family oFamily = abi::getFamily(o.abi); + if (family != oFamily) { + return family != abi::Family::none; + } + + if (int(target.abi) - int(abi) < int(target.abi) - int(o.abi)) { + return true; + } + } + return config.isBetterThan(o.config, &target.config); +} + +bool SplitDescription::match(const SplitDescription& o) const { + if (abi != abi::Variant::none) { + abi::Family family = abi::getFamily(abi); + abi::Family oFamily = abi::getFamily(o.abi); + if (family != oFamily) { + return false; + } + + if (int(abi) > int(o.abi)) { + return false; + } + } + return config.match(o.config); +} + +String8 SplitDescription::toString() const { + String8 extension; + if (abi != abi::Variant::none) { + if (extension.isEmpty()) { + extension.append(":"); + } else { + extension.append("-"); + } + extension.append(abi::toString(abi)); + } + String8 str(config.toString()); + str.append(extension); + return str; +} + +ssize_t parseAbi(const Vector<String8>& parts, const ssize_t index, + SplitDescription* outSplit) { + const ssize_t N = parts.size(); + abi::Variant abi = abi::Variant::none; + ssize_t endIndex = index; + if (parts[endIndex] == "arm64") { + endIndex++; + if (endIndex < N) { + if (parts[endIndex] == "v8a") { + endIndex++; + abi = abi::Variant::arm64_v8a; + } + } + } else if (parts[endIndex] == "armeabi") { + endIndex++; + abi = abi::Variant::armeabi; + if (endIndex < N) { + if (parts[endIndex] == "v7a") { + endIndex++; + abi = abi::Variant::armeabi_v7a; + } + } + } else if (parts[endIndex] == "x86") { + endIndex++; + abi = abi::Variant::x86; + } else if (parts[endIndex] == "x86_64") { + endIndex++; + abi = abi::Variant::x86_64; + } else if (parts[endIndex] == "mips") { + endIndex++; + abi = abi::Variant::mips; + } else if (parts[endIndex] == "mips64") { + endIndex++; + abi = abi::Variant::mips64; + } + + if (abi == abi::Variant::none && endIndex != index) { + return -1; + } + + if (outSplit != NULL) { + outSplit->abi = abi; + } + return endIndex; +} + +bool SplitDescription::parse(const String8& str, SplitDescription* outSplit) { + ssize_t index = str.find(":"); + + String8 configStr; + String8 extensionStr; + if (index >= 0) { + configStr.setTo(str.string(), index); + extensionStr.setTo(str.string() + index + 1); + } else { + configStr.setTo(str); + } + + SplitDescription split; + if (!AaptConfig::parse(configStr, &split.config)) { + return false; + } + + Vector<String8> parts = AaptUtil::splitAndLowerCase(extensionStr, '-'); + const ssize_t N = parts.size(); + index = 0; + + if (extensionStr.length() == 0) { + goto success; + } + + index = parseAbi(parts, index, &split); + if (index < 0) { + return false; + } else { + if (index == N) { + goto success; + } + } + + // Unrecognized + return false; + +success: + if (outSplit != NULL) { + *outSplit = split; + } + return true; +} + +} // namespace split |