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