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 "Rule.h" 1840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 1940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski#include <utils/String8.h> 2040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2140e8eefbedcafc51948945647d746daaee092f16Adam Lesinskiusing namespace android; 2240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2340e8eefbedcafc51948945647d746daaee092f16Adam Lesinskinamespace split { 2440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 2540e8eefbedcafc51948945647d746daaee092f16Adam Lesinskiinline static void indentStr(String8& str, int indent) { 2640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski while (indent > 0) { 2740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(" "); 2840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indent--; 2940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 3040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 3140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 32dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam LesinskiRule::Rule(const Rule& rhs) 33dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski : RefBase() 34dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , op(rhs.op) 35dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , key(rhs.key) 36dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , negate(rhs.negate) 37dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , stringArgs(rhs.stringArgs) 38dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , longArgs(rhs.longArgs) 39dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski , subrules(rhs.subrules) { 40dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski} 41dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski 4240e8eefbedcafc51948945647d746daaee092f16Adam LesinskiString8 Rule::toJson(int indent) const { 4340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski String8 str; 4440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 4540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("{\n"); 4640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indent++; 4740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 4840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"op\": \""); 4940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski switch (op) { 5040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case ALWAYS_TRUE: 5140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("ALWAYS_TRUE"); 5240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 5340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case GREATER_THAN: 5440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("GREATER_THAN"); 5540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 5640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case LESS_THAN: 5740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("LESS_THAN"); 5840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 5940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case EQUALS: 6040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("EQUALS"); 6140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 6240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case AND_SUBRULES: 6340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("AND_SUBRULES"); 6440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 6540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case OR_SUBRULES: 6640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("OR_SUBRULES"); 6740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 6840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case CONTAINS_ANY: 6940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("CONTAINS_ANY"); 7040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 7140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski default: 7240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.appendFormat("%d", op); 7340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 7440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 7540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\""); 7640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 7740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (negate) { 7840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(",\n"); 7940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 8040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"negate\": true"); 8140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 8240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 8340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski bool includeKey = true; 8440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski switch (op) { 8540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case AND_SUBRULES: 8640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case OR_SUBRULES: 8740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski includeKey = false; 8840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 8940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski default: 9040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 9140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 9240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 9340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (includeKey) { 9440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(",\n"); 9540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 9640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"property\": \""); 9740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski switch (key) { 9840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case NONE: 9940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("NONE"); 10040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 10140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case SDK_VERSION: 10240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("SDK_VERSION"); 10340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 10440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case SCREEN_DENSITY: 10540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("SCREEN_DENSITY"); 10640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 10740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case NATIVE_PLATFORM: 10840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("NATIVE_PLATFORM"); 10940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 11040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case LANGUAGE: 11140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("LANGUAGE"); 11240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 11340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski default: 11440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.appendFormat("%d", key); 11540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 11640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 11740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\""); 11840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 11940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 12040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (op == AND_SUBRULES || op == OR_SUBRULES) { 12140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(",\n"); 12240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 12340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"subrules\": [\n"); 12440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t subruleCount = subrules.size(); 12540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < subruleCount; i++) { 12640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(subrules[i]->toJson(indent + 1)); 12740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (i != subruleCount - 1) { 12840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(","); 12940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 13040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\n"); 13140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 13240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 13340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("]"); 13440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } else { 13540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski switch (key) { 13640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case SDK_VERSION: 13740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case SCREEN_DENSITY: { 13840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(",\n"); 13940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 14040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"args\": ["); 14140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t argCount = longArgs.size(); 14240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < argCount; i++) { 14340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (i != 0) { 14440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(", "); 14540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.appendFormat("%d", longArgs[i]); 14740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 14840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("]"); 14940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 15040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 15140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case LANGUAGE: 15240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski case NATIVE_PLATFORM: { 15340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(",\n"); 15440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 15540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\"args\": ["); 15640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t argCount = stringArgs.size(); 15740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < argCount; i++) { 15840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (i != 0) { 15940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(", "); 16040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 16140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append(stringArgs[i]); 16240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 16340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("]"); 16440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 16540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 16640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski default: 16740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski break; 16840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 16940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 17040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("\n"); 17140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indent--; 17240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski indentStr(str, indent); 17340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski str.append("}"); 17440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return str; 17540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 17640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 17740e8eefbedcafc51948945647d746daaee092f16Adam Lesinskisp<Rule> Rule::simplify(sp<Rule> rule) { 17840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (rule->op != AND_SUBRULES && rule->op != OR_SUBRULES) { 17940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return rule; 18040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 18140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 18240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski Vector<sp<Rule> > newSubrules; 18340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski newSubrules.setCapacity(rule->subrules.size()); 18440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t subruleCount = rule->subrules.size(); 18540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski for (size_t i = 0; i < subruleCount; i++) { 18640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski sp<Rule> simplifiedRule = simplify(rule->subrules.editItemAt(i)); 18740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (simplifiedRule != NULL) { 18840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (simplifiedRule->op == rule->op) { 18940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski newSubrules.appendVector(simplifiedRule->subrules); 19040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } else { 19140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski newSubrules.add(simplifiedRule); 19240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 19340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 19440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 19540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 19640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski const size_t newSubruleCount = newSubrules.size(); 19740e8eefbedcafc51948945647d746daaee092f16Adam Lesinski if (newSubruleCount == 0) { 19840e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return NULL; 19940e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } else if (subruleCount == 1) { 20040e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return newSubrules.editTop(); 20140e8eefbedcafc51948945647d746daaee092f16Adam Lesinski } 20240e8eefbedcafc51948945647d746daaee092f16Adam Lesinski rule->subrules = newSubrules; 20340e8eefbedcafc51948945647d746daaee092f16Adam Lesinski return rule; 20440e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} 20540e8eefbedcafc51948945647d746daaee092f16Adam Lesinski 20640e8eefbedcafc51948945647d746daaee092f16Adam Lesinski} // namespace split 207