173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Copyright 2016, The Android Open Source Project 373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Licensed under the Apache License, Version 2.0 (the "License"); 573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** you may not use this file except in compliance with the License. 673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** You may obtain a copy of the License at 773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** http://www.apache.org/licenses/LICENSE-2.0 973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 1073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Unless required by applicable law or agreed to in writing, software 1173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** distributed under the License is distributed on an "AS IS" BASIS, 1273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** See the License for the specific language governing permissions and 1473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** limitations under the License. 1573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 1673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 1773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <algorithm> 1873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <inttypes.h> 19c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe#include <limits> 2073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <random> 211842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe#include <regex> 2273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/android.h> 2373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/avc.h> 2473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <stdlib.h> 2573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <string.h> 2673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/capability.h> 2773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/prctl.h> 2873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/stat.h> 2973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/wait.h> 3073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/logging.h> 3273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/macros.h> 3373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/stringprintf.h> 346db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe#include <android-base/strings.h> 3573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/fs.h> 3673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/properties.h> 3754e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe#include <dex2oat_return_codes.h> 387823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 3973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <private/android_filesystem_config.h> 4073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 416c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey#include "dexopt.h" 42f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "file_parsing.h" 43f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "globals.h" 44c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe#include "installd_constants.h" 45f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "installd_deps.h" // Need to fill in requirements of commands. 46f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "otapreopt_utils.h" 47f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "system_properties.h" 48f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "utils.h" 496c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey 5073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifndef LOG_TAG 5173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define LOG_TAG "otapreopt" 5273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 5373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define BUFFER_MAX 1024 /* input buffer for commands */ 5573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define TOKEN_MAX 16 /* max number of arguments in buffer */ 5673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define REPLY_MAX 256 /* largest reply allowed */ 5773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::EndsWith; 596db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Join; 606db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Split; 6156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::StartsWith; 6273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeusing android::base::StringPrintf; 6373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace android { 6573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace installd { 6673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 67ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// Check expected values for dexopt flags. If you need to change this: 68ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// 69ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// RUN AN A/B OTA TO MAKE SURE THINGS STILL WORK! 70ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// 71ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// You most likely need to increase the protocol version and all that entails! 72ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 73ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_PUBLIC == 1 << 1, "DEXOPT_PUBLIC unexpected."); 74ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_DEBUGGABLE == 1 << 2, "DEXOPT_DEBUGGABLE unexpected."); 75ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_BOOTCOMPLETE == 1 << 3, "DEXOPT_BOOTCOMPLETE unexpected."); 76ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_PROFILE_GUIDED == 1 << 4, "DEXOPT_PROFILE_GUIDED unexpected."); 77ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_SECONDARY_DEX == 1 << 5, "DEXOPT_SECONDARY_DEX unexpected."); 78ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_FORCE == 1 << 6, "DEXOPT_FORCE unexpected."); 79ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_STORAGE_CE == 1 << 7, "DEXOPT_STORAGE_CE unexpected."); 80ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_STORAGE_DE == 1 << 8, "DEXOPT_STORAGE_DE unexpected."); 81ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 82ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_MASK == 0x1fe, "DEXOPT_MASK unexpected."); 83ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 84ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 85ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 8673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 8773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundDown(T x, typename std::decay<T>::type n) { 8873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 8973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 9073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 9273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 9373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return RoundDown(x + n - 1, n); 9473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 9573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeclass OTAPreoptService { 9773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe public: 9873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Main driver. Performs the following steps. 9973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 1) Parse options (read system properties etc from B partition). 10173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 2) Read in package data. 10373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 3) Prepare environment variables. 10573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 4) Prepare(compile) boot image, if necessary. 10773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 5) Run update. 10973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int Main(int argc, char** argv) { 110d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!ReadArguments(argc, argv)) { 111d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed reading command line."; 112d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 1; 113d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 114d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 11573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadSystemProperties()) { 11673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR)<< "Failed reading system properties."; 117d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 2; 11873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 11973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 12073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadEnvironment()) { 12173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed reading environment properties."; 122d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 3; 12373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 125d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CheckAndInitializeInstalldGlobals()) { 126d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed initializing globals."; 127d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 4; 12873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PrepareEnvironment(); 13173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 132d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!PrepareBootImage(/* force */ false)) { 13373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed preparing boot image."; 134d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 5; 13573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_retcode = RunPreopt(); 13873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return dexopt_retcode; 14073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 14173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 142d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int GetProperty(const char* key, char* value, const char* default_value) const { 14373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* prop_value = system_properties_.GetProperty(key); 14473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prop_value == nullptr) { 14573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (default_value == nullptr) { 14673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 14773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 14873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Copy in the default value. 14973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, default_value, kPropertyValueMax - 1); 15073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[kPropertyValueMax - 1] = 0; 15173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return strlen(default_value);// TODO: Need to truncate? 15273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 15373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 15473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, prop_value->data(), size); 15573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[size] = 0; 15673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return static_cast<int>(size); 15773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 15873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 159d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string GetOTADataDirectory() const { 160d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str()); 161d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 162d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 163d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetTargetSlot() const { 164d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return target_slot_; 165d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 166d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 16773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeprivate: 168d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 169c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe struct Parameters { 170c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *apk_path; 171c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe uid_t uid; 172c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *pkgName; 173c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *instruction_set; 174c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe int dexopt_needed; 175c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* oat_dir; 176c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe int dexopt_flags; 177c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* compiler_filter; 178c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* volume_uuid; 179c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* shared_libraries; 180c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* se_info; 181c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe }; 182c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 18373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadSystemProperties() { 1841842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe static constexpr const char* kPropertyFiles[] = { 1851842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe "/default.prop", "/system/build.prop" 1861842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }; 1871842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1881842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 1891842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!system_properties_.Load(kPropertyFiles[i])) { 1901842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return false; 1911842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1921842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1931842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1941842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 19573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 19673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 19773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadEnvironment() { 1981842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // Parse the environment variables from init.environ.rc, which have the form 1991842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // export NAME VALUE 2001842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // For simplicity, don't respect string quotation. The values we are interested in can be 2011842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // encoded without them. 2021842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 2031842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 2041842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::smatch export_match; 2051842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!std::regex_match(line, export_match, export_regex)) { 2061842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2071842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 2081842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2091842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (export_match.size() != 3) { 2101842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2111842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 2121842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2131842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string name = export_match[1].str(); 2141842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string value = export_match[2].str(); 2151842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2161842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe system_properties_.SetProperty(name, value); 2171842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2181842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2191842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }); 2201842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!parse_result) { 22173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 22273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 224d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { 225d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 22673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 227d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName); 228d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 229d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) { 230d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 231d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 232d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName); 233d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 234d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) { 235d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 236d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 237d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName); 238d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 239d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) { 240d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 241d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 242d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME); 24373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 24473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 24573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 247d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidData() const { 248d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_data_; 249d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 250d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 251d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidRoot() const { 252d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_root_; 253d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 254d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 255d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string GetOtaDirectoryPrefix() const { 256d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return GetAndroidData() + "/ota"; 257d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 258d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 259d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool CheckAndInitializeInstalldGlobals() { 260d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We 261d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // do not use any datapath that includes this, but we'll still have to set it. 262d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr); 263d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0); 264d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (result != 0) { 265d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable"; 266d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 267d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 268d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 269d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) { 270d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not initialize globals; exiting."; 271d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 272d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 273d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 274d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // This is different from the normal installd. We only do the base 275d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // directory, the rest will be created on demand when each app is compiled. 276d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) { 277d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix(); 278d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 279d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 280d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 281d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 282d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 283d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 284c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ParseUInt(const char* in, uint32_t* out) { 285c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe char* end; 286c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe long long int result = strtoll(in, &end, 0); 287c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (in == end || *end != '\0') { 288c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 289c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 290c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (result < std::numeric_limits<uint32_t>::min() || 291c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe std::numeric_limits<uint32_t>::max() < result) { 292c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 293c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 294c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe *out = static_cast<uint32_t>(result); 295c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return true; 296c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 297d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 298c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArguments(int argc, char** argv) { 299c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Expected command line: 300c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // target-slot [version] dexopt {DEXOPT_PARAMETERS} 301d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 302d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* target_slot_arg = argv[1]; 303d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (target_slot_arg == nullptr) { 304d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 305d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 306d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 307d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Sanitize value. Only allow (a-zA-Z0-9_)+. 308d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe target_slot_ = target_slot_arg; 309fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe if (!ValidateTargetSlotSuffix(target_slot_)) { 310fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe LOG(ERROR) << "Target slot suffix not legal: " << target_slot_; 311fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe return false; 312d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 313d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 314c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for version or "dexopt" next. 315c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argv[2] == nullptr) { 316c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Missing parameters"; 317c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 318c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 319c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 320c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (std::string("dexopt").compare(argv[2]) == 0) { 321c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // This is version 1 (N) or pre-versioning version 2. 322c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int kV2ArgCount = 1 // "otapreopt" 323c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // slot 324c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // "dexopt" 325c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // apk_path 326c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // uid 327c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // pkg 328c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // isa 329c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // dexopt_needed 330c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // oat_dir 331c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // dexopt_flags 332c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // filter 333c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // volume 334c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // libs 335645e79cb279575b569bd308e7dfb09645e19d0ddAndreas Gampe + 1; // seinfo 336c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argc == kV2ArgCount) { 337c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV2(argc, argv, false); 338c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } else { 339c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV1(argc, argv); 340c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 341c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 342c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 343c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe uint32_t version; 344c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (!ParseUInt(argv[2], &version)) { 345c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Could not parse version: " << argv[2]; 346c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 347c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 348c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 349c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (version) { 350c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 351c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV2(argc, argv, true); 352c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 353c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe default: 354c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Unsupported version " << version; 355c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 356c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 357c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 358c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 359c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) { 360c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t dexopt_index = versioned ? 3 : 2; 361c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 362c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for "dexopt". 363c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argv[dexopt_index] == nullptr) { 364c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Missing parameters"; 365c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 366c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 367c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (std::string("dexopt").compare(argv[dexopt_index]) != 0) { 368c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Expected \"dexopt\""; 369c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 370c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 371c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 372c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t param_index = 0; 373c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe for (;; ++param_index) { 374c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* param = argv[dexopt_index + 1 + param_index]; 375c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param == nullptr) { 376c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 377c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 378c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 379c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (param_index) { 380c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 0: 381c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.apk_path = param; 382c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 383c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 384c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 1: 385c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.uid = atoi(param); 386c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 387c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 388c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 389c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.pkgName = param; 390c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 391c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 392c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 3: 393c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.instruction_set = param; 394c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 395c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 396c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 4: 397c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_needed = atoi(param); 398c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 399c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 400c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 5: 401c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.oat_dir = param; 402c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 403c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 404c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 6: 405c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_flags = atoi(param); 406c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 407c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 408c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 7: 409c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.compiler_filter = param; 410c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 411c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 412c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 8: 413c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.volume_uuid = ParseNull(param); 414c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 415c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 416c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 9: 417c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.shared_libraries = ParseNull(param); 418c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 419c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 420c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 10: 421c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.se_info = ParseNull(param); 422c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 423c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 424c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe default: 425c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Too many arguments, got " << param; 426c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 427c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 428c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 429c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 430c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param_index != 11) { 431c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Not enough parameters"; 432c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 433c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 434c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 435c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return true; 436c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 437c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 438c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe static int ReplaceMask(int input, int old_mask, int new_mask) { 439c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return (input & old_mask) != 0 ? new_mask : 0; 440c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 441c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 442c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) { 443c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for "dexopt". 444d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (argv[2] == nullptr) { 445d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 446d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 447d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 448d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (std::string("dexopt").compare(argv[2]) != 0) { 449c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Expected \"dexopt\""; 450d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 451d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 452d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 453c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t param_index = 0; 454c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe for (;; ++param_index) { 455c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* param = argv[3 + param_index]; 456c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param == nullptr) { 457c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 458c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 459c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 460c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (param_index) { 461c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 0: 462c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.apk_path = param; 463c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 464c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 465c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 1: 466c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.uid = atoi(param); 467c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 468c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 469c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 470c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.pkgName = param; 471c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 472c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 473c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 3: 474c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.instruction_set = param; 475c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 476c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 477c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 4: { 478c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Version 1 had: 479c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_DEX2OAT_NEEDED = 1 480c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_PATCHOAT_NEEDED = 2 481c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_SELF_PATCHOAT_NEEDED = 3 482c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // We will simply use DEX2OAT_FROM_SCRATCH. 483c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH; 484c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 485c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 486c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 487