Rule.cpp revision 40e8eefbedcafc51948945647d746daaee092f16
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "Rule.h" 18 19#include <utils/String8.h> 20 21using namespace android; 22 23namespace split { 24 25inline static void indentStr(String8& str, int indent) { 26 while (indent > 0) { 27 str.append(" "); 28 indent--; 29 } 30} 31 32String8 Rule::toJson(int indent) const { 33 String8 str; 34 indentStr(str, indent); 35 str.append("{\n"); 36 indent++; 37 indentStr(str, indent); 38 str.append("\"op\": \""); 39 switch (op) { 40 case ALWAYS_TRUE: 41 str.append("ALWAYS_TRUE"); 42 break; 43 case GREATER_THAN: 44 str.append("GREATER_THAN"); 45 break; 46 case LESS_THAN: 47 str.append("LESS_THAN"); 48 break; 49 case EQUALS: 50 str.append("EQUALS"); 51 break; 52 case AND_SUBRULES: 53 str.append("AND_SUBRULES"); 54 break; 55 case OR_SUBRULES: 56 str.append("OR_SUBRULES"); 57 break; 58 case CONTAINS_ANY: 59 str.append("CONTAINS_ANY"); 60 break; 61 default: 62 str.appendFormat("%d", op); 63 break; 64 } 65 str.append("\""); 66 67 if (negate) { 68 str.append(",\n"); 69 indentStr(str, indent); 70 str.append("\"negate\": true"); 71 } 72 73 bool includeKey = true; 74 switch (op) { 75 case AND_SUBRULES: 76 case OR_SUBRULES: 77 includeKey = false; 78 break; 79 default: 80 break; 81 } 82 83 if (includeKey) { 84 str.append(",\n"); 85 indentStr(str, indent); 86 str.append("\"property\": \""); 87 switch (key) { 88 case NONE: 89 str.append("NONE"); 90 break; 91 case SDK_VERSION: 92 str.append("SDK_VERSION"); 93 break; 94 case SCREEN_DENSITY: 95 str.append("SCREEN_DENSITY"); 96 break; 97 case NATIVE_PLATFORM: 98 str.append("NATIVE_PLATFORM"); 99 break; 100 case LANGUAGE: 101 str.append("LANGUAGE"); 102 break; 103 default: 104 str.appendFormat("%d", key); 105 break; 106 } 107 str.append("\""); 108 } 109 110 if (op == AND_SUBRULES || op == OR_SUBRULES) { 111 str.append(",\n"); 112 indentStr(str, indent); 113 str.append("\"subrules\": [\n"); 114 const size_t subruleCount = subrules.size(); 115 for (size_t i = 0; i < subruleCount; i++) { 116 str.append(subrules[i]->toJson(indent + 1)); 117 if (i != subruleCount - 1) { 118 str.append(","); 119 } 120 str.append("\n"); 121 } 122 indentStr(str, indent); 123 str.append("]"); 124 } else { 125 switch (key) { 126 case SDK_VERSION: 127 case SCREEN_DENSITY: { 128 str.append(",\n"); 129 indentStr(str, indent); 130 str.append("\"args\": ["); 131 const size_t argCount = longArgs.size(); 132 for (size_t i = 0; i < argCount; i++) { 133 if (i != 0) { 134 str.append(", "); 135 } 136 str.appendFormat("%d", longArgs[i]); 137 } 138 str.append("]"); 139 break; 140 } 141 case LANGUAGE: 142 case NATIVE_PLATFORM: { 143 str.append(",\n"); 144 indentStr(str, indent); 145 str.append("\"args\": ["); 146 const size_t argCount = stringArgs.size(); 147 for (size_t i = 0; i < argCount; i++) { 148 if (i != 0) { 149 str.append(", "); 150 } 151 str.append(stringArgs[i]); 152 } 153 str.append("]"); 154 break; 155 } 156 default: 157 break; 158 } 159 } 160 str.append("\n"); 161 indent--; 162 indentStr(str, indent); 163 str.append("}"); 164 return str; 165} 166 167sp<Rule> Rule::simplify(sp<Rule> rule) { 168 if (rule->op != AND_SUBRULES && rule->op != OR_SUBRULES) { 169 return rule; 170 } 171 172 Vector<sp<Rule> > newSubrules; 173 newSubrules.setCapacity(rule->subrules.size()); 174 const size_t subruleCount = rule->subrules.size(); 175 for (size_t i = 0; i < subruleCount; i++) { 176 sp<Rule> simplifiedRule = simplify(rule->subrules.editItemAt(i)); 177 if (simplifiedRule != NULL) { 178 if (simplifiedRule->op == rule->op) { 179 newSubrules.appendVector(simplifiedRule->subrules); 180 } else { 181 newSubrules.add(simplifiedRule); 182 } 183 } 184 } 185 186 const size_t newSubruleCount = newSubrules.size(); 187 if (newSubruleCount == 0) { 188 return NULL; 189 } else if (subruleCount == 1) { 190 return newSubrules.editTop(); 191 } 192 rule->subrules = newSubrules; 193 return rule; 194} 195 196} // namespace split 197