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