xref: /aosp_15_r20/frameworks/native/cmds/installd/otapreopt_parameters.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  ** Copyright 2016, The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  **
4*38e8c45fSAndroid Build Coastguard Worker  ** Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  ** you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  ** You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  **
8*38e8c45fSAndroid Build Coastguard Worker  **     http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  **
10*38e8c45fSAndroid Build Coastguard Worker  ** Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  ** distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  ** See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  ** limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "otapreopt_parameters.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <cstring>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <android-base/logging.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include "dexopt.h"
24*38e8c45fSAndroid Build Coastguard Worker #include "installd_constants.h"
25*38e8c45fSAndroid Build Coastguard Worker #include "otapreopt_utils.h"
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #ifndef LOG_TAG
28*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "otapreopt"
29*38e8c45fSAndroid Build Coastguard Worker #endif
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker namespace android {
32*38e8c45fSAndroid Build Coastguard Worker namespace installd {
33*38e8c45fSAndroid Build Coastguard Worker 
ParseBool(const char * in)34*38e8c45fSAndroid Build Coastguard Worker static bool ParseBool(const char* in) {
35*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(in, "true") == 0) {
36*38e8c45fSAndroid Build Coastguard Worker         return true;
37*38e8c45fSAndroid Build Coastguard Worker     }
38*38e8c45fSAndroid Build Coastguard Worker     return false;
39*38e8c45fSAndroid Build Coastguard Worker }
40*38e8c45fSAndroid Build Coastguard Worker 
ParseNull(const char * arg)41*38e8c45fSAndroid Build Coastguard Worker static const char* ParseNull(const char* arg) {
42*38e8c45fSAndroid Build Coastguard Worker     return (strcmp(arg, "!") == 0) ? nullptr : arg;
43*38e8c45fSAndroid Build Coastguard Worker }
44*38e8c45fSAndroid Build Coastguard Worker 
ParseUInt(const char * in,uint32_t * out)45*38e8c45fSAndroid Build Coastguard Worker static bool ParseUInt(const char* in, uint32_t* out) {
46*38e8c45fSAndroid Build Coastguard Worker     char* end;
47*38e8c45fSAndroid Build Coastguard Worker     long long int result = strtoll(in, &end, 0);
48*38e8c45fSAndroid Build Coastguard Worker     if (in == end || *end != '\0') {
49*38e8c45fSAndroid Build Coastguard Worker         return false;
50*38e8c45fSAndroid Build Coastguard Worker     }
51*38e8c45fSAndroid Build Coastguard Worker     if (result < std::numeric_limits<uint32_t>::min() ||
52*38e8c45fSAndroid Build Coastguard Worker             std::numeric_limits<uint32_t>::max() < result) {
53*38e8c45fSAndroid Build Coastguard Worker         return false;
54*38e8c45fSAndroid Build Coastguard Worker     }
55*38e8c45fSAndroid Build Coastguard Worker     *out = static_cast<uint32_t>(result);
56*38e8c45fSAndroid Build Coastguard Worker     return true;
57*38e8c45fSAndroid Build Coastguard Worker }
58*38e8c45fSAndroid Build Coastguard Worker 
ReadArguments(int argc,const char ** argv)59*38e8c45fSAndroid Build Coastguard Worker bool OTAPreoptParameters::ReadArguments(int argc, const char** argv) {
60*38e8c45fSAndroid Build Coastguard Worker     // Expected command line:
61*38e8c45fSAndroid Build Coastguard Worker     //   target-slot [version] dexopt {DEXOPT_PARAMETERS}
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker     const char* target_slot_arg = argv[1];
64*38e8c45fSAndroid Build Coastguard Worker     if (target_slot_arg == nullptr) {
65*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Missing parameters";
66*38e8c45fSAndroid Build Coastguard Worker         return false;
67*38e8c45fSAndroid Build Coastguard Worker     }
68*38e8c45fSAndroid Build Coastguard Worker     // Sanitize value. Only allow (a-zA-Z0-9_)+.
69*38e8c45fSAndroid Build Coastguard Worker     target_slot = target_slot_arg;
70*38e8c45fSAndroid Build Coastguard Worker     if (!ValidateTargetSlotSuffix(target_slot)) {
71*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Target slot suffix not legal: " << target_slot;
72*38e8c45fSAndroid Build Coastguard Worker         return false;
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker     // Check for version or "dexopt" next.
76*38e8c45fSAndroid Build Coastguard Worker     if (argv[2] == nullptr) {
77*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Missing parameters";
78*38e8c45fSAndroid Build Coastguard Worker         return false;
79*38e8c45fSAndroid Build Coastguard Worker     }
80*38e8c45fSAndroid Build Coastguard Worker 
81*38e8c45fSAndroid Build Coastguard Worker     if (std::string("dexopt").compare(argv[2]) == 0) {
82*38e8c45fSAndroid Build Coastguard Worker         // This is version 1 (N) or pre-versioning version 2.
83*38e8c45fSAndroid Build Coastguard Worker         constexpr int kV2ArgCount =   1   // "otapreopt"
84*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // slot
85*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // "dexopt"
86*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // apk_path
87*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // uid
88*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // pkg
89*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // isa
90*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // dexopt_needed
91*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // oat_dir
92*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // dexopt_flags
93*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // filter
94*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // volume
95*38e8c45fSAndroid Build Coastguard Worker                                     + 1   // libs
96*38e8c45fSAndroid Build Coastguard Worker                                     + 1;  // seinfo
97*38e8c45fSAndroid Build Coastguard Worker         if (argc == kV2ArgCount) {
98*38e8c45fSAndroid Build Coastguard Worker             return ReadArgumentsPostV1(2, argv, false);
99*38e8c45fSAndroid Build Coastguard Worker         } else {
100*38e8c45fSAndroid Build Coastguard Worker             return ReadArgumentsV1(argv);
101*38e8c45fSAndroid Build Coastguard Worker         }
102*38e8c45fSAndroid Build Coastguard Worker     }
103*38e8c45fSAndroid Build Coastguard Worker 
104*38e8c45fSAndroid Build Coastguard Worker     uint32_t version;
105*38e8c45fSAndroid Build Coastguard Worker     if (!ParseUInt(argv[2], &version)) {
106*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Could not parse version: " << argv[2];
107*38e8c45fSAndroid Build Coastguard Worker         return false;
108*38e8c45fSAndroid Build Coastguard Worker     }
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker     return ReadArgumentsPostV1(version, argv, true);
111*38e8c45fSAndroid Build Coastguard Worker }
112*38e8c45fSAndroid Build Coastguard Worker 
ReplaceMask(int input,int old_mask,int new_mask)113*38e8c45fSAndroid Build Coastguard Worker static int ReplaceMask(int input, int old_mask, int new_mask) {
114*38e8c45fSAndroid Build Coastguard Worker     return (input & old_mask) != 0 ? new_mask : 0;
115*38e8c45fSAndroid Build Coastguard Worker }
116*38e8c45fSAndroid Build Coastguard Worker 
SetDefaultsForPostV1Arguments()117*38e8c45fSAndroid Build Coastguard Worker void OTAPreoptParameters::SetDefaultsForPostV1Arguments() {
118*38e8c45fSAndroid Build Coastguard Worker     // Set se_info to null. It is only relevant for secondary dex files, which we won't
119*38e8c45fSAndroid Build Coastguard Worker     // receive from a v1 A side.
120*38e8c45fSAndroid Build Coastguard Worker     se_info = nullptr;
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     // Set downgrade to false. It is only relevant when downgrading compiler
123*38e8c45fSAndroid Build Coastguard Worker     // filter, which is not the case during ota.
124*38e8c45fSAndroid Build Coastguard Worker     downgrade = false;
125*38e8c45fSAndroid Build Coastguard Worker 
126*38e8c45fSAndroid Build Coastguard Worker     // Set target_sdk_version to 0, ie the platform SDK version. This is
127*38e8c45fSAndroid Build Coastguard Worker     // conservative and may force some classes to verify at runtime.
128*38e8c45fSAndroid Build Coastguard Worker     target_sdk_version = 0;
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker     // Set the profile name to the primary apk profile.
131*38e8c45fSAndroid Build Coastguard Worker     profile_name = "primary.prof";
132*38e8c45fSAndroid Build Coastguard Worker 
133*38e8c45fSAndroid Build Coastguard Worker     // By default we don't have a dex metadata file.
134*38e8c45fSAndroid Build Coastguard Worker     dex_metadata_path = nullptr;
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     // The compilation reason is ab-ota (match the system property pm.dexopt.ab-ota)
137*38e8c45fSAndroid Build Coastguard Worker     compilation_reason = "ab-ota";
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     // Flag is enabled by default for A/B otas.
140*38e8c45fSAndroid Build Coastguard Worker     dexopt_flags = DEXOPT_GENERATE_COMPACT_DEX;
141*38e8c45fSAndroid Build Coastguard Worker }
142*38e8c45fSAndroid Build Coastguard Worker 
ReadArgumentsV1(const char ** argv)143*38e8c45fSAndroid Build Coastguard Worker bool OTAPreoptParameters::ReadArgumentsV1(const char** argv) {
144*38e8c45fSAndroid Build Coastguard Worker     // Check for "dexopt".
145*38e8c45fSAndroid Build Coastguard Worker     if (argv[2] == nullptr) {
146*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Missing parameters";
147*38e8c45fSAndroid Build Coastguard Worker         return false;
148*38e8c45fSAndroid Build Coastguard Worker     }
149*38e8c45fSAndroid Build Coastguard Worker     if (std::string("dexopt").compare(argv[2]) != 0) {
150*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Expected \"dexopt\" but found: " << argv[2];
151*38e8c45fSAndroid Build Coastguard Worker         return false;
152*38e8c45fSAndroid Build Coastguard Worker     }
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     SetDefaultsForPostV1Arguments();
155*38e8c45fSAndroid Build Coastguard Worker 
156*38e8c45fSAndroid Build Coastguard Worker     size_t param_index = 0;
157*38e8c45fSAndroid Build Coastguard Worker     for (;; ++param_index) {
158*38e8c45fSAndroid Build Coastguard Worker         const char* param = argv[3 + param_index];
159*38e8c45fSAndroid Build Coastguard Worker         if (param == nullptr) {
160*38e8c45fSAndroid Build Coastguard Worker             break;
161*38e8c45fSAndroid Build Coastguard Worker         }
162*38e8c45fSAndroid Build Coastguard Worker 
163*38e8c45fSAndroid Build Coastguard Worker         switch (param_index) {
164*38e8c45fSAndroid Build Coastguard Worker             case 0:
165*38e8c45fSAndroid Build Coastguard Worker                 apk_path = param;
166*38e8c45fSAndroid Build Coastguard Worker                 break;
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker             case 1:
169*38e8c45fSAndroid Build Coastguard Worker                 uid = atoi(param);
170*38e8c45fSAndroid Build Coastguard Worker                 break;
171*38e8c45fSAndroid Build Coastguard Worker 
172*38e8c45fSAndroid Build Coastguard Worker             case 2:
173*38e8c45fSAndroid Build Coastguard Worker                 pkgName = param;
174*38e8c45fSAndroid Build Coastguard Worker                 break;
175*38e8c45fSAndroid Build Coastguard Worker 
176*38e8c45fSAndroid Build Coastguard Worker             case 3:
177*38e8c45fSAndroid Build Coastguard Worker                 instruction_set = param;
178*38e8c45fSAndroid Build Coastguard Worker                 break;
179*38e8c45fSAndroid Build Coastguard Worker 
180*38e8c45fSAndroid Build Coastguard Worker             case 4: {
181*38e8c45fSAndroid Build Coastguard Worker                 // Version 1 had:
182*38e8c45fSAndroid Build Coastguard Worker                 //   DEXOPT_DEX2OAT_NEEDED       = 1
183*38e8c45fSAndroid Build Coastguard Worker                 //   DEXOPT_PATCHOAT_NEEDED      = 2
184*38e8c45fSAndroid Build Coastguard Worker                 //   DEXOPT_SELF_PATCHOAT_NEEDED = 3
185*38e8c45fSAndroid Build Coastguard Worker                 // We will simply use DEX2OAT_FROM_SCRATCH.
186*38e8c45fSAndroid Build Coastguard Worker                 dexopt_needed = DEX2OAT_FROM_SCRATCH;
187*38e8c45fSAndroid Build Coastguard Worker                 break;
188*38e8c45fSAndroid Build Coastguard Worker             }
189*38e8c45fSAndroid Build Coastguard Worker 
190*38e8c45fSAndroid Build Coastguard Worker             case 5:
191*38e8c45fSAndroid Build Coastguard Worker                 oat_dir = param;
192*38e8c45fSAndroid Build Coastguard Worker                 break;
193*38e8c45fSAndroid Build Coastguard Worker 
194*38e8c45fSAndroid Build Coastguard Worker             case 6: {
195*38e8c45fSAndroid Build Coastguard Worker                 // Version 1 had:
196*38e8c45fSAndroid Build Coastguard Worker                 constexpr int OLD_DEXOPT_PUBLIC         = 1 << 1;
197*38e8c45fSAndroid Build Coastguard Worker                 // Note: DEXOPT_SAFEMODE has been removed.
198*38e8c45fSAndroid Build Coastguard Worker                 // constexpr int OLD_DEXOPT_SAFEMODE       = 1 << 2;
199*38e8c45fSAndroid Build Coastguard Worker                 constexpr int OLD_DEXOPT_DEBUGGABLE     = 1 << 3;
200*38e8c45fSAndroid Build Coastguard Worker                 constexpr int OLD_DEXOPT_BOOTCOMPLETE   = 1 << 4;
201*38e8c45fSAndroid Build Coastguard Worker                 constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
202*38e8c45fSAndroid Build Coastguard Worker                 constexpr int OLD_DEXOPT_OTA            = 1 << 6;
203*38e8c45fSAndroid Build Coastguard Worker                 static_assert(DEXOPT_GENERATE_COMPACT_DEX > OLD_DEXOPT_OTA, "must not overlap");
204*38e8c45fSAndroid Build Coastguard Worker                 int input = atoi(param);
205*38e8c45fSAndroid Build Coastguard Worker                 dexopt_flags |=
206*38e8c45fSAndroid Build Coastguard Worker                         ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
207*38e8c45fSAndroid Build Coastguard Worker                         ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
208*38e8c45fSAndroid Build Coastguard Worker                         ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
209*38e8c45fSAndroid Build Coastguard Worker                         ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) |
210*38e8c45fSAndroid Build Coastguard Worker                         ReplaceMask(input, OLD_DEXOPT_OTA, 0);
211*38e8c45fSAndroid Build Coastguard Worker                 break;
212*38e8c45fSAndroid Build Coastguard Worker             }
213*38e8c45fSAndroid Build Coastguard Worker 
214*38e8c45fSAndroid Build Coastguard Worker             case 7:
215*38e8c45fSAndroid Build Coastguard Worker                 compiler_filter = param;
216*38e8c45fSAndroid Build Coastguard Worker                 break;
217*38e8c45fSAndroid Build Coastguard Worker 
218*38e8c45fSAndroid Build Coastguard Worker             case 8:
219*38e8c45fSAndroid Build Coastguard Worker                 volume_uuid = ParseNull(param);
220*38e8c45fSAndroid Build Coastguard Worker                 break;
221*38e8c45fSAndroid Build Coastguard Worker 
222*38e8c45fSAndroid Build Coastguard Worker             case 9:
223*38e8c45fSAndroid Build Coastguard Worker                 shared_libraries = ParseNull(param);
224*38e8c45fSAndroid Build Coastguard Worker                 break;
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker             default:
227*38e8c45fSAndroid Build Coastguard Worker                 LOG(ERROR) << "Too many arguments, got " << param;
228*38e8c45fSAndroid Build Coastguard Worker                 return false;
229*38e8c45fSAndroid Build Coastguard Worker         }
230*38e8c45fSAndroid Build Coastguard Worker     }
231*38e8c45fSAndroid Build Coastguard Worker 
232*38e8c45fSAndroid Build Coastguard Worker     if (param_index != 10) {
233*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Not enough parameters";
234*38e8c45fSAndroid Build Coastguard Worker         return false;
235*38e8c45fSAndroid Build Coastguard Worker     }
236*38e8c45fSAndroid Build Coastguard Worker 
237*38e8c45fSAndroid Build Coastguard Worker     return true;
238*38e8c45fSAndroid Build Coastguard Worker }
239*38e8c45fSAndroid Build Coastguard Worker 
ReadArgumentsPostV1(uint32_t version,const char ** argv,bool versioned)240*38e8c45fSAndroid Build Coastguard Worker bool OTAPreoptParameters::ReadArgumentsPostV1(uint32_t version, const char** argv, bool versioned) {
241*38e8c45fSAndroid Build Coastguard Worker     size_t num_args_expected = 0;
242*38e8c45fSAndroid Build Coastguard Worker     switch (version) {
243*38e8c45fSAndroid Build Coastguard Worker         case 2: num_args_expected = 11; break;
244*38e8c45fSAndroid Build Coastguard Worker         case 3: num_args_expected = 12; break;
245*38e8c45fSAndroid Build Coastguard Worker         case 4: num_args_expected = 13; break;
246*38e8c45fSAndroid Build Coastguard Worker         case 5: num_args_expected = 14; break;
247*38e8c45fSAndroid Build Coastguard Worker         case 6: num_args_expected = 15; break;
248*38e8c45fSAndroid Build Coastguard Worker         case 7:
249*38e8c45fSAndroid Build Coastguard Worker         // Version 8 adds a new dexopt flag: DEXOPT_GENERATE_COMPACT_DEX
250*38e8c45fSAndroid Build Coastguard Worker         case 8: num_args_expected = 16; break;
251*38e8c45fSAndroid Build Coastguard Worker         // Version 9 adds a new dexopt flag: DEXOPT_GENERATE_APP_IMAGE
252*38e8c45fSAndroid Build Coastguard Worker         case 9: num_args_expected = 16; break;
253*38e8c45fSAndroid Build Coastguard Worker         // Version 10 is a compatibility bump.
254*38e8c45fSAndroid Build Coastguard Worker         case 10: num_args_expected = 16; break;
255*38e8c45fSAndroid Build Coastguard Worker         default:
256*38e8c45fSAndroid Build Coastguard Worker             LOG(ERROR) << "Don't know how to read arguments for version " << version;
257*38e8c45fSAndroid Build Coastguard Worker             return false;
258*38e8c45fSAndroid Build Coastguard Worker     }
259*38e8c45fSAndroid Build Coastguard Worker     size_t dexopt_index = versioned ? 3 : 2;
260*38e8c45fSAndroid Build Coastguard Worker 
261*38e8c45fSAndroid Build Coastguard Worker     // Check for "dexopt".
262*38e8c45fSAndroid Build Coastguard Worker     if (argv[dexopt_index] == nullptr) {
263*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Missing parameters";
264*38e8c45fSAndroid Build Coastguard Worker         return false;
265*38e8c45fSAndroid Build Coastguard Worker     }
266*38e8c45fSAndroid Build Coastguard Worker     if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
267*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Expected \"dexopt\" but found: " << argv[dexopt_index];
268*38e8c45fSAndroid Build Coastguard Worker         return false;
269*38e8c45fSAndroid Build Coastguard Worker     }
270*38e8c45fSAndroid Build Coastguard Worker 
271*38e8c45fSAndroid Build Coastguard Worker     // Validate the number of arguments.
272*38e8c45fSAndroid Build Coastguard Worker     size_t num_args_actual = 0;
273*38e8c45fSAndroid Build Coastguard Worker     while (argv[dexopt_index + 1 + num_args_actual] != nullptr) {
274*38e8c45fSAndroid Build Coastguard Worker         num_args_actual++;
275*38e8c45fSAndroid Build Coastguard Worker     }
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker     if (num_args_actual != num_args_expected) {
278*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Invalid number of arguments. expected="
279*38e8c45fSAndroid Build Coastguard Worker                 << num_args_expected << " actual=" << num_args_actual;
280*38e8c45fSAndroid Build Coastguard Worker         return false;
281*38e8c45fSAndroid Build Coastguard Worker     }
282*38e8c45fSAndroid Build Coastguard Worker 
283*38e8c45fSAndroid Build Coastguard Worker     // The number of arguments is OK.
284*38e8c45fSAndroid Build Coastguard Worker     // Configure the default values for the parameters that were added after V1.
285*38e8c45fSAndroid Build Coastguard Worker     // The default values will be overwritten in case they are passed as arguments.
286*38e8c45fSAndroid Build Coastguard Worker     SetDefaultsForPostV1Arguments();
287*38e8c45fSAndroid Build Coastguard Worker 
288*38e8c45fSAndroid Build Coastguard Worker     for (size_t param_index = 0; param_index < num_args_actual; ++param_index) {
289*38e8c45fSAndroid Build Coastguard Worker         const char* param = argv[dexopt_index + 1 + param_index];
290*38e8c45fSAndroid Build Coastguard Worker         switch (param_index) {
291*38e8c45fSAndroid Build Coastguard Worker             case 0:
292*38e8c45fSAndroid Build Coastguard Worker                 apk_path = param;
293*38e8c45fSAndroid Build Coastguard Worker                 break;
294*38e8c45fSAndroid Build Coastguard Worker 
295*38e8c45fSAndroid Build Coastguard Worker             case 1:
296*38e8c45fSAndroid Build Coastguard Worker                 uid = atoi(param);
297*38e8c45fSAndroid Build Coastguard Worker                 break;
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker             case 2:
300*38e8c45fSAndroid Build Coastguard Worker                 pkgName = param;
301*38e8c45fSAndroid Build Coastguard Worker                 break;
302*38e8c45fSAndroid Build Coastguard Worker 
303*38e8c45fSAndroid Build Coastguard Worker             case 3:
304*38e8c45fSAndroid Build Coastguard Worker                 instruction_set = param;
305*38e8c45fSAndroid Build Coastguard Worker                 break;
306*38e8c45fSAndroid Build Coastguard Worker 
307*38e8c45fSAndroid Build Coastguard Worker             case 4:
308*38e8c45fSAndroid Build Coastguard Worker                 dexopt_needed = atoi(param);
309*38e8c45fSAndroid Build Coastguard Worker                 break;
310*38e8c45fSAndroid Build Coastguard Worker 
311*38e8c45fSAndroid Build Coastguard Worker             case 5:
312*38e8c45fSAndroid Build Coastguard Worker                 oat_dir = param;
313*38e8c45fSAndroid Build Coastguard Worker                 break;
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker             case 6:
316*38e8c45fSAndroid Build Coastguard Worker                 dexopt_flags = atoi(param);
317*38e8c45fSAndroid Build Coastguard Worker                 // Add CompactDex generation flag for versions less than 8 since it wasn't passed
318*38e8c45fSAndroid Build Coastguard Worker                 // from the package manager. Only conditionally set the flag here so that it can
319*38e8c45fSAndroid Build Coastguard Worker                 // be fully controlled by the package manager.
320*38e8c45fSAndroid Build Coastguard Worker                 dexopt_flags |= (version < 8) ? DEXOPT_GENERATE_COMPACT_DEX : 0u;
321*38e8c45fSAndroid Build Coastguard Worker                 break;
322*38e8c45fSAndroid Build Coastguard Worker 
323*38e8c45fSAndroid Build Coastguard Worker             case 7:
324*38e8c45fSAndroid Build Coastguard Worker                 compiler_filter = param;
325*38e8c45fSAndroid Build Coastguard Worker                 break;
326*38e8c45fSAndroid Build Coastguard Worker 
327*38e8c45fSAndroid Build Coastguard Worker             case 8:
328*38e8c45fSAndroid Build Coastguard Worker                 volume_uuid = ParseNull(param);
329*38e8c45fSAndroid Build Coastguard Worker                 break;
330*38e8c45fSAndroid Build Coastguard Worker 
331*38e8c45fSAndroid Build Coastguard Worker             case 9:
332*38e8c45fSAndroid Build Coastguard Worker                 shared_libraries = ParseNull(param);
333*38e8c45fSAndroid Build Coastguard Worker                 break;
334*38e8c45fSAndroid Build Coastguard Worker 
335*38e8c45fSAndroid Build Coastguard Worker             case 10:
336*38e8c45fSAndroid Build Coastguard Worker                 se_info = ParseNull(param);
337*38e8c45fSAndroid Build Coastguard Worker                 break;
338*38e8c45fSAndroid Build Coastguard Worker 
339*38e8c45fSAndroid Build Coastguard Worker             case 11:
340*38e8c45fSAndroid Build Coastguard Worker                 downgrade = ParseBool(param);
341*38e8c45fSAndroid Build Coastguard Worker                 break;
342*38e8c45fSAndroid Build Coastguard Worker 
343*38e8c45fSAndroid Build Coastguard Worker             case 12:
344*38e8c45fSAndroid Build Coastguard Worker                 target_sdk_version = atoi(param);
345*38e8c45fSAndroid Build Coastguard Worker                 break;
346*38e8c45fSAndroid Build Coastguard Worker 
347*38e8c45fSAndroid Build Coastguard Worker             case 13:
348*38e8c45fSAndroid Build Coastguard Worker                 profile_name = ParseNull(param);
349*38e8c45fSAndroid Build Coastguard Worker                 break;
350*38e8c45fSAndroid Build Coastguard Worker 
351*38e8c45fSAndroid Build Coastguard Worker             case 14:
352*38e8c45fSAndroid Build Coastguard Worker                 dex_metadata_path = ParseNull(param);
353*38e8c45fSAndroid Build Coastguard Worker                 break;
354*38e8c45fSAndroid Build Coastguard Worker 
355*38e8c45fSAndroid Build Coastguard Worker             case 15:
356*38e8c45fSAndroid Build Coastguard Worker                 compilation_reason = ParseNull(param);
357*38e8c45fSAndroid Build Coastguard Worker                 break;
358*38e8c45fSAndroid Build Coastguard Worker 
359*38e8c45fSAndroid Build Coastguard Worker             default:
360*38e8c45fSAndroid Build Coastguard Worker                 LOG(FATAL) << "Should not get here. Did you call ReadArguments "
361*38e8c45fSAndroid Build Coastguard Worker                         << "with the right expectation? index=" << param_index
362*38e8c45fSAndroid Build Coastguard Worker                         << " num_args=" << num_args_actual;
363*38e8c45fSAndroid Build Coastguard Worker                 return false;
364*38e8c45fSAndroid Build Coastguard Worker         }
365*38e8c45fSAndroid Build Coastguard Worker     }
366*38e8c45fSAndroid Build Coastguard Worker 
367*38e8c45fSAndroid Build Coastguard Worker     if (version < 10) {
368*38e8c45fSAndroid Build Coastguard Worker         // Do not accept '&' as shared libraries from versions prior to 10. These may lead
369*38e8c45fSAndroid Build Coastguard Worker         // to runtime crashes. The server side of version 10+ should send the correct
370*38e8c45fSAndroid Build Coastguard Worker         // context in almost all cases (e.g., only for actual shared packages).
371*38e8c45fSAndroid Build Coastguard Worker         if (shared_libraries != nullptr && std::string("&") == shared_libraries) {
372*38e8c45fSAndroid Build Coastguard Worker             return false;
373*38e8c45fSAndroid Build Coastguard Worker         }
374*38e8c45fSAndroid Build Coastguard Worker     }
375*38e8c45fSAndroid Build Coastguard Worker 
376*38e8c45fSAndroid Build Coastguard Worker     return true;
377*38e8c45fSAndroid Build Coastguard Worker }
378*38e8c45fSAndroid Build Coastguard Worker 
379*38e8c45fSAndroid Build Coastguard Worker }  // namespace installd
380*38e8c45fSAndroid Build Coastguard Worker }  // namespace android
381