RuleGenerator.cpp revision 40e8eefbedcafc51948945647d746daaee092f16
140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski/* 240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * Copyright (C) 2014 The Android Open Source Project 340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * 440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * you may not use this file except in compliance with the License. 640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * You may obtain a copy of the License at 740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * 840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * 1040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * See the License for the specific language governing permissions and 1440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski * limitations under the License. 1540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski */ 1640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 1740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include "RuleGenerator.h" 1840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 1940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include <algorithm> 2040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include <cmath> 2140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include <vector> 2240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include <androidfw/ResourceTypes.h> 2340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2440e8eefbedcafc51948945647d746daaee092f16Adam Lesinskiusing namespace android; 2540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2640e8eefbedcafc51948945647d746daaee092f16Adam Lesinskinamespace split { 2740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski// Calculate the point at which the density selection changes between l and h. 2940e8eefbedcafc51948945647d746daaee092f16Adam Lesinskistatic inline int findMid(int l, int h) { 3040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski double root = sqrt((h*h) + (8*l*h)); 3140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return (double(-h) + root) / 2.0; 3240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 3340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 3440e8eefbedcafc51948945647d746daaee092f16Adam Lesinskisp<Rule> RuleGenerator::generateDensity(const Vector<int>& allDensities, size_t index) { 3540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> densityRule = new Rule(); 3640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski densityRule->op = Rule::AND_SUBRULES; 3740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 3840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const bool anyDensity = allDensities[index] == ResTable_config::DENSITY_ANY; 3940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> any = new Rule(); 4040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski any->op = Rule::EQUALS; 4140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski any->key = Rule::SCREEN_DENSITY; 4240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski any->longArgs.add((int)ResTable_config::DENSITY_ANY); 4340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski any->negate = !anyDensity; 4440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski densityRule->subrules.add(any); 4540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 4640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (!anyDensity) { 4740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (index > 0) { 4840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> gt = new Rule(); 4940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski gt->op = Rule::GREATER_THAN; 5040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski gt->key = Rule::SCREEN_DENSITY; 5140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski gt->longArgs.add(findMid(allDensities[index - 1], allDensities[index]) - 1); 5240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski densityRule->subrules.add(gt); 5340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 5440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 5540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (index + 1 < allDensities.size() && allDensities[index + 1] != ResTable_config::DENSITY_ANY) { 5640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> lt = new Rule(); 5740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski lt->op = Rule::LESS_THAN; 5840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski lt->key = Rule::SCREEN_DENSITY; 5940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski lt->longArgs.add(findMid(allDensities[index], allDensities[index + 1])); 6040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski densityRule->subrules.add(lt); 6140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 6240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 6340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return densityRule; 6440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 6540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 6640e8eefbedcafc51948945647d746daaee092f16Adam Lesinskisp<Rule> RuleGenerator::generateAbi(const Vector<abi::Variant>& splitAbis, size_t index) { 6740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const abi::Variant thisAbi = splitAbis[index]; 6840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const std::vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi)); 6940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 7040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski std::vector<abi::Variant>::const_iterator start = 7140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski std::find(familyVariants.begin(), familyVariants.end(), thisAbi); 7240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 7340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski std::vector<abi::Variant>::const_iterator end = familyVariants.end(); 7440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (index + 1 < splitAbis.size()) { 7540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski end = std::find(start, familyVariants.end(), splitAbis[index + 1]); 7640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 7740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 7840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> abiRule = new Rule(); 7940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski abiRule->op = Rule::CONTAINS_ANY; 8040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski abiRule->key = Rule::NATIVE_PLATFORM; 8140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski while (start != end) { 8240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski abiRule->stringArgs.add(String8(abi::toString(*start))); 8340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski ++start; 8440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 8540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return abiRule; 8640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 8740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 8840e8eefbedcafc51948945647d746daaee092f16Adam Lesinskisp<Rule> RuleGenerator::generate(const SortedVector<SplitDescription>& group, size_t index) { 8940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> rootRule = new Rule(); 9040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rootRule->op = Rule::AND_SUBRULES; 9140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 9240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[index].config.locale != 0) { 9340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> locale = new Rule(); 9440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski locale->op = Rule::EQUALS; 9540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski locale->key = Rule::LANGUAGE; 9640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski char str[RESTABLE_MAX_LOCALE_LEN]; 9740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski group[index].config.getBcp47Locale(str); 9840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski locale->stringArgs.add(String8(str)); 9940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rootRule->subrules.add(locale); 10040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 10140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 10240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[index].config.sdkVersion != 0) { 10340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> sdk = new Rule(); 10440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sdk->op = Rule::GREATER_THAN; 10540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sdk->key = Rule::SDK_VERSION; 10640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sdk->longArgs.add(group[index].config.sdkVersion - 1); 10740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rootRule->subrules.add(sdk); 10840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 10940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 11040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[index].config.density != 0) { 11140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski size_t densityIndex = 0; 11240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski Vector<int> allDensities; 11340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allDensities.add(group[index].config.density); 11440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 11540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t groupSize = group.size(); 11640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < groupSize; i++) { 11740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[i].config.density != group[index].config.density) { 11840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski // This group differs by density. 11940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allDensities.clear(); 12040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t j = 0; j < groupSize; j++) { 12140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allDensities.add(group[j].config.density); 12240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 12340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski densityIndex = index; 12440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 12540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 12640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 12740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rootRule->subrules.add(generateDensity(allDensities, densityIndex)); 12840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 12940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 13040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[index].abi != abi::Variant::none) { 13140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski size_t abiIndex = 0; 13240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski Vector<abi::Variant> allVariants; 13340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allVariants.add(group[index].abi); 13440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 13540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t groupSize = group.size(); 13640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < groupSize; i++) { 13740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (group[i].abi != group[index].abi) { 13840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski // This group differs by ABI. 13940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allVariants.clear(); 14040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t j = 0; j < groupSize; j++) { 14140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski allVariants.add(group[j].abi); 14240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski abiIndex = index; 14440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 14540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rootRule->subrules.add(generateAbi(allVariants, abiIndex)); 14840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 15040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return rootRule; 15140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 15240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 15340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} // namespace split 154