xref: /aosp_15_r20/frameworks/base/tools/split-select/SplitDescription.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 "SplitDescription.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include "aapt/AaptConfig.h"
20*d57664e9SAndroid Build Coastguard Worker #include "aapt/AaptUtil.h"
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker #include <utils/String8.h>
23*d57664e9SAndroid Build Coastguard Worker #include <utils/Vector.h>
24*d57664e9SAndroid Build Coastguard Worker 
25*d57664e9SAndroid Build Coastguard Worker using namespace android;
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker namespace split {
28*d57664e9SAndroid Build Coastguard Worker 
SplitDescription()29*d57664e9SAndroid Build Coastguard Worker SplitDescription::SplitDescription()
30*d57664e9SAndroid Build Coastguard Worker : abi(abi::Variant_none) {
31*d57664e9SAndroid Build Coastguard Worker }
32*d57664e9SAndroid Build Coastguard Worker 
compare(const SplitDescription & rhs) const33*d57664e9SAndroid Build Coastguard Worker int SplitDescription::compare(const SplitDescription& rhs) const {
34*d57664e9SAndroid Build Coastguard Worker     int cmp;
35*d57664e9SAndroid Build Coastguard Worker     cmp = (int)abi - (int)rhs.abi;
36*d57664e9SAndroid Build Coastguard Worker     if (cmp != 0) return cmp;
37*d57664e9SAndroid Build Coastguard Worker     return config.compareLogical(rhs.config);
38*d57664e9SAndroid Build Coastguard Worker }
39*d57664e9SAndroid Build Coastguard Worker 
isBetterThan(const SplitDescription & o,const SplitDescription & target) const40*d57664e9SAndroid Build Coastguard Worker bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescription& target) const {
41*d57664e9SAndroid Build Coastguard Worker     if (abi != abi::Variant_none || o.abi != abi::Variant_none) {
42*d57664e9SAndroid Build Coastguard Worker         abi::Family family = abi::getFamily(abi);
43*d57664e9SAndroid Build Coastguard Worker         abi::Family oFamily = abi::getFamily(o.abi);
44*d57664e9SAndroid Build Coastguard Worker         if (family != oFamily) {
45*d57664e9SAndroid Build Coastguard Worker             return family != abi::Family_none;
46*d57664e9SAndroid Build Coastguard Worker         }
47*d57664e9SAndroid Build Coastguard Worker 
48*d57664e9SAndroid Build Coastguard Worker         if (int(target.abi) - int(abi) < int(target.abi) - int(o.abi)) {
49*d57664e9SAndroid Build Coastguard Worker             return true;
50*d57664e9SAndroid Build Coastguard Worker         }
51*d57664e9SAndroid Build Coastguard Worker     }
52*d57664e9SAndroid Build Coastguard Worker     return config.isBetterThan(o.config, &target.config);
53*d57664e9SAndroid Build Coastguard Worker }
54*d57664e9SAndroid Build Coastguard Worker 
match(const SplitDescription & o) const55*d57664e9SAndroid Build Coastguard Worker bool SplitDescription::match(const SplitDescription& o) const {
56*d57664e9SAndroid Build Coastguard Worker     if (abi != abi::Variant_none) {
57*d57664e9SAndroid Build Coastguard Worker         abi::Family family = abi::getFamily(abi);
58*d57664e9SAndroid Build Coastguard Worker         abi::Family oFamily = abi::getFamily(o.abi);
59*d57664e9SAndroid Build Coastguard Worker         if (family != oFamily) {
60*d57664e9SAndroid Build Coastguard Worker             return false;
61*d57664e9SAndroid Build Coastguard Worker         }
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker         if (int(abi) > int(o.abi)) {
64*d57664e9SAndroid Build Coastguard Worker             return false;
65*d57664e9SAndroid Build Coastguard Worker         }
66*d57664e9SAndroid Build Coastguard Worker     }
67*d57664e9SAndroid Build Coastguard Worker     return config.match(o.config);
68*d57664e9SAndroid Build Coastguard Worker }
69*d57664e9SAndroid Build Coastguard Worker 
toString() const70*d57664e9SAndroid Build Coastguard Worker String8 SplitDescription::toString() const {
71*d57664e9SAndroid Build Coastguard Worker     String8 extension;
72*d57664e9SAndroid Build Coastguard Worker     if (abi != abi::Variant_none) {
73*d57664e9SAndroid Build Coastguard Worker         if (extension.empty()) {
74*d57664e9SAndroid Build Coastguard Worker             extension.append(":");
75*d57664e9SAndroid Build Coastguard Worker         } else {
76*d57664e9SAndroid Build Coastguard Worker             extension.append("-");
77*d57664e9SAndroid Build Coastguard Worker         }
78*d57664e9SAndroid Build Coastguard Worker         extension.append(abi::toString(abi));
79*d57664e9SAndroid Build Coastguard Worker     }
80*d57664e9SAndroid Build Coastguard Worker     String8 str(config.toString());
81*d57664e9SAndroid Build Coastguard Worker     str.append(extension);
82*d57664e9SAndroid Build Coastguard Worker     return str;
83*d57664e9SAndroid Build Coastguard Worker }
84*d57664e9SAndroid Build Coastguard Worker 
parseAbi(const Vector<String8> & parts,const ssize_t index,SplitDescription * outSplit)85*d57664e9SAndroid Build Coastguard Worker ssize_t parseAbi(const Vector<String8>& parts, const ssize_t index,
86*d57664e9SAndroid Build Coastguard Worker         SplitDescription* outSplit) {
87*d57664e9SAndroid Build Coastguard Worker     const ssize_t N = parts.size();
88*d57664e9SAndroid Build Coastguard Worker     abi::Variant abi = abi::Variant_none;
89*d57664e9SAndroid Build Coastguard Worker     ssize_t endIndex = index;
90*d57664e9SAndroid Build Coastguard Worker     if (parts[endIndex] == "arm64") {
91*d57664e9SAndroid Build Coastguard Worker         endIndex++;
92*d57664e9SAndroid Build Coastguard Worker         if (endIndex < N) {
93*d57664e9SAndroid Build Coastguard Worker             if (parts[endIndex] == "v8a") {
94*d57664e9SAndroid Build Coastguard Worker                 endIndex++;
95*d57664e9SAndroid Build Coastguard Worker                 abi = abi::Variant_arm64_v8a;
96*d57664e9SAndroid Build Coastguard Worker             }
97*d57664e9SAndroid Build Coastguard Worker         }
98*d57664e9SAndroid Build Coastguard Worker     } else if (parts[endIndex] == "armeabi") {
99*d57664e9SAndroid Build Coastguard Worker         endIndex++;
100*d57664e9SAndroid Build Coastguard Worker         abi = abi::Variant_armeabi;
101*d57664e9SAndroid Build Coastguard Worker         if (endIndex < N) {
102*d57664e9SAndroid Build Coastguard Worker             if (parts[endIndex] == "v7a") {
103*d57664e9SAndroid Build Coastguard Worker                 endIndex++;
104*d57664e9SAndroid Build Coastguard Worker                 abi = abi::Variant_armeabi_v7a;
105*d57664e9SAndroid Build Coastguard Worker             }
106*d57664e9SAndroid Build Coastguard Worker         }
107*d57664e9SAndroid Build Coastguard Worker     } else if (parts[endIndex] == "x86") {
108*d57664e9SAndroid Build Coastguard Worker         endIndex++;
109*d57664e9SAndroid Build Coastguard Worker         abi = abi::Variant_x86;
110*d57664e9SAndroid Build Coastguard Worker     } else if (parts[endIndex] == "x86_64") {
111*d57664e9SAndroid Build Coastguard Worker         endIndex++;
112*d57664e9SAndroid Build Coastguard Worker         abi = abi::Variant_x86_64;
113*d57664e9SAndroid Build Coastguard Worker     } else if (parts[endIndex] == "mips") {
114*d57664e9SAndroid Build Coastguard Worker         endIndex++;
115*d57664e9SAndroid Build Coastguard Worker         abi = abi::Variant_mips;
116*d57664e9SAndroid Build Coastguard Worker     } else if (parts[endIndex] == "mips64") {
117*d57664e9SAndroid Build Coastguard Worker         endIndex++;
118*d57664e9SAndroid Build Coastguard Worker         abi = abi::Variant_mips64;
119*d57664e9SAndroid Build Coastguard Worker     }
120*d57664e9SAndroid Build Coastguard Worker 
121*d57664e9SAndroid Build Coastguard Worker     if (abi == abi::Variant_none && endIndex != index) {
122*d57664e9SAndroid Build Coastguard Worker         return -1;
123*d57664e9SAndroid Build Coastguard Worker     }
124*d57664e9SAndroid Build Coastguard Worker 
125*d57664e9SAndroid Build Coastguard Worker     if (outSplit != NULL) {
126*d57664e9SAndroid Build Coastguard Worker         outSplit->abi = abi;
127*d57664e9SAndroid Build Coastguard Worker     }
128*d57664e9SAndroid Build Coastguard Worker     return endIndex;
129*d57664e9SAndroid Build Coastguard Worker }
130*d57664e9SAndroid Build Coastguard Worker 
parse(const String8 & str,SplitDescription * outSplit)131*d57664e9SAndroid Build Coastguard Worker bool SplitDescription::parse(const String8& str, SplitDescription* outSplit) {
132*d57664e9SAndroid Build Coastguard Worker     ssize_t index = str.find(":");
133*d57664e9SAndroid Build Coastguard Worker 
134*d57664e9SAndroid Build Coastguard Worker     String8 configStr;
135*d57664e9SAndroid Build Coastguard Worker     String8 extensionStr;
136*d57664e9SAndroid Build Coastguard Worker     if (index >= 0) {
137*d57664e9SAndroid Build Coastguard Worker         configStr = String8(str.c_str(), index);
138*d57664e9SAndroid Build Coastguard Worker         extensionStr = (str.c_str() + index + 1);
139*d57664e9SAndroid Build Coastguard Worker     } else {
140*d57664e9SAndroid Build Coastguard Worker         configStr = str;
141*d57664e9SAndroid Build Coastguard Worker     }
142*d57664e9SAndroid Build Coastguard Worker 
143*d57664e9SAndroid Build Coastguard Worker     SplitDescription split;
144*d57664e9SAndroid Build Coastguard Worker     if (!AaptConfig::parse(configStr, &split.config)) {
145*d57664e9SAndroid Build Coastguard Worker         return false;
146*d57664e9SAndroid Build Coastguard Worker     }
147*d57664e9SAndroid Build Coastguard Worker 
148*d57664e9SAndroid Build Coastguard Worker     Vector<String8> parts = AaptUtil::splitAndLowerCase(extensionStr, '-');
149*d57664e9SAndroid Build Coastguard Worker     const ssize_t N = parts.size();
150*d57664e9SAndroid Build Coastguard Worker     index = 0;
151*d57664e9SAndroid Build Coastguard Worker 
152*d57664e9SAndroid Build Coastguard Worker     if (extensionStr.length() == 0) {
153*d57664e9SAndroid Build Coastguard Worker         goto success;
154*d57664e9SAndroid Build Coastguard Worker     }
155*d57664e9SAndroid Build Coastguard Worker 
156*d57664e9SAndroid Build Coastguard Worker     index = parseAbi(parts, index, &split);
157*d57664e9SAndroid Build Coastguard Worker     if (index < 0) {
158*d57664e9SAndroid Build Coastguard Worker         return false;
159*d57664e9SAndroid Build Coastguard Worker     } else {
160*d57664e9SAndroid Build Coastguard Worker         if (index == N) {
161*d57664e9SAndroid Build Coastguard Worker             goto success;
162*d57664e9SAndroid Build Coastguard Worker         }
163*d57664e9SAndroid Build Coastguard Worker     }
164*d57664e9SAndroid Build Coastguard Worker 
165*d57664e9SAndroid Build Coastguard Worker     // Unrecognized
166*d57664e9SAndroid Build Coastguard Worker     return false;
167*d57664e9SAndroid Build Coastguard Worker 
168*d57664e9SAndroid Build Coastguard Worker success:
169*d57664e9SAndroid Build Coastguard Worker     if (outSplit != NULL) {
170*d57664e9SAndroid Build Coastguard Worker         *outSplit = split;
171*d57664e9SAndroid Build Coastguard Worker     }
172*d57664e9SAndroid Build Coastguard Worker     return true;
173*d57664e9SAndroid Build Coastguard Worker }
174*d57664e9SAndroid Build Coastguard Worker 
175*d57664e9SAndroid Build Coastguard Worker } // namespace split
176