17d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle/*
27d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * Copyright (C) 2017 The Android Open Source Project
37d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle *
47d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * Licensed under the Apache License, Version 2.0 (the "License");
57d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * you may not use this file except in compliance with the License.
67d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * You may obtain a copy of the License at
77d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle *
87d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle *      http://www.apache.org/licenses/LICENSE-2.0
97d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle *
107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * Unless required by applicable law or agreed to in writing, software
117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * distributed under the License is distributed on an "AS IS" BASIS,
127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * See the License for the specific language governing permissions and
147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle * limitations under the License.
157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle */
167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle#include <cstdlib>
1829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <fcntl.h>
197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <stdlib.h>
207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <string.h>
2129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <sys/types.h>
2229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <sys/stat.h>
237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <android-base/file.h>
257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <android-base/logging.h>
267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <android-base/stringprintf.h>
2729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <android-base/unique_fd.h>
2829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <cutils/properties.h>
3029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include <gtest/gtest.h>
327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <selinux/android.h>
3429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle#include <selinux/avc.h>
3529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include "dexopt.h"
377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include "InstalldNativeService.h"
387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include "globals.h"
397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include "tests/test_utils.h"
407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#include "utils.h"
417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleusing android::base::ReadFully;
4329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleusing android::base::unique_fd;
4429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlenamespace android {
467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlenamespace installd {
477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle// TODO(calin): try to dedup this code.
497d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#if defined(__arm__)
507d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "arm";
517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#elif defined(__aarch64__)
527d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "arm64";
537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#elif defined(__mips__) && !defined(__LP64__)
547d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "mips";
557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#elif defined(__mips__) && defined(__LP64__)
567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "mips64";
577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#elif defined(__i386__)
587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "x86";
597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#elif defined(__x86_64__)
607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "x86_64";
617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#else
627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const std::string kRuntimeIsa = "none";
637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle#endif
647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleint get_property(const char *key, char *value, const char *default_value) {
667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    return property_get(key, value, default_value);
677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlebool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        const char *instruction_set) {
717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlebool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        const char *instruction_set) {
767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    return calculate_odex_file_path_default(path, apk_path, instruction_set);
777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlebool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    return create_cache_path_default(path, src, instruction_set);
817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic void run_cmd(const std::string& cmd) {
847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    system(cmd.c_str());
857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic void mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    ::mkdir(path.c_str(), mode);
897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    ::chown(path.c_str(), owner, group);
907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    ::chmod(path.c_str(), mode);
917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
9329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravlestatic int log_callback(int type, const char *fmt, ...) { // NOLINT
9429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    va_list ap;
9529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    int priority;
9629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
9729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    switch (type) {
9829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        case SELINUX_WARNING:
9929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            priority = ANDROID_LOG_WARN;
10029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            break;
10129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        case SELINUX_INFO:
10229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            priority = ANDROID_LOG_INFO;
10329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            break;
10429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        default:
10529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            priority = ANDROID_LOG_ERROR;
10629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            break;
10729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
10829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    va_start(ap, fmt);
10929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG_PRI_VA(priority, "SELinux", fmt, ap);
11029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    va_end(ap);
11129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    return 0;
11229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
11329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
11429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravlestatic bool init_selinux() {
11529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    int selinux_enabled = (is_selinux_enabled() > 0);
11629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
11729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    union selinux_callback cb;
11829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    cb.func_log = log_callback;
11929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    selinux_set_callback(SELINUX_CB_LOG, cb);
12029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
12129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    if (selinux_enabled && selinux_status_open(true) < 0) {
12229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        LOG(ERROR) << "Could not open selinux status; exiting";
12329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return false;
12429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
12529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
12629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    return true;
12729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
12829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
1297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle// Base64 encoding of a simple dex files with 2 methods.
1307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravlestatic const char kDexFile[] =
1317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "UEsDBBQAAAAIAOiOYUs9y6BLCgEAABQCAAALABwAY2xhc3Nlcy5kZXhVVAkAA/Ns+lkOHv1ZdXgL"
1327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "AAEEI+UCAASIEwAAS0mt4DIwNmX4qpn7j/2wA7v7N+ZvoQpCJRlVx5SWa4YaiDAxMBQwMDBUhJkI"
1337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "MUBBDyMDAzsDRJwFxAdioBDDHAYEYAbiFUAM1M5wAIhFGCGKDIDYAogdgNgDiH2BOAiI0xghekDm"
1347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "sQIxGxQzM6ACRijNhCbOhCZfyohdPYyuh8szgtVkMkLsLhAAqeCDi+ejibPZZOZlltgxsDnqZSWW"
1357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "JTKwOUFoZh9HayDhZM0g5AMS0M9JzEvX90/KSk0usWZgDAMaws5nAyXBzmpoYGlgAjsAyJoBMp0b"
1367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "zQ8gGhbOTEhhzYwU3qxIYc2GFN6MClC/AhUyKUDMAYU9M1Qc5F8GKBscVgIQM0FxCwBQSwECHgMU"
1377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "AAAACADojmFLPcugSwoBAAAUAgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAA/Ns"
1387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    "+ll1eAsAAQQj5QIABIgTAABQSwUGAAAAAAEAAQBRAAAATwEAAAAA";
1397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleclass DexoptTest : public testing::Test {
1427d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleprotected:
1437d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr bool kDebug = false;
1447d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr uid_t kSystemUid = 1000;
1457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr uid_t kSystemGid = 1000;
1467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr int32_t kOSdkVersion = 25;
1477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
1487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    static constexpr int32_t kTestUserId = 0;
149d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    static constexpr uid_t kTestAppId = 19999;
150d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
151d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId);
152d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId);
1537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1547d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    InstalldNativeService* service_;
1557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::unique_ptr<std::string> volume_uuid_;
1567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string package_name_;
1570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string apk_path_;
1587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string app_apk_dir_;
1597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string app_private_dir_ce_;
1607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string app_private_dir_de_;
1617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string se_info_;
162c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    std::string app_oat_dir_;
1637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    int64_t ce_data_inode_;
1657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_ce_;
1677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_ce_link_;
1687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_de_;
1697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
1717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        setenv("ANDROID_LOG_TAGS", "*:v", 1);
1727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        android::base::InitLogging(nullptr);
17329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Initialize the globals holding the file system main paths (/data/, /system/ etc..).
17429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // This is needed in order to compute the application and profile paths.
17529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(init_globals_from_data_and_root());
17629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Initialize selinux log callbacks.
17729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // This ensures that selinux is up and running and re-directs the selinux messages
17829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // to logcat (in order to make it easier to investigate test results).
17929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(init_selinux());
1807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        service_ = new InstalldNativeService();
1817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        volume_uuid_ = nullptr;
1837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        package_name_ = "com.installd.test.dexopt";
1847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        se_info_ = "default";
1857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_apk_dir_ = android_app_dir + package_name_;
1867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        create_mock_app();
1887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
1897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void TearDown() {
1917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        if (!kDebug) {
1927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            service_->destroyAppData(
1937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_, package_name_, kTestUserId, kAppDataFlags, ce_data_inode_);
1947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_apk_dir_);
1957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_private_dir_ce_);
1967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_private_dir_de_);
1977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        }
1987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        delete service_;
1997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2007d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void create_mock_app() {
2027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create the oat dir.
203c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        app_oat_dir_ = app_apk_dir_ + "/oat";
2047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755);
205c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        service_->createOatDir(app_oat_dir_, kRuntimeIsa);
2067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Copy the primary apk.
2080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        apk_path_ = app_apk_dir_ + "/base.jar";
2090d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, apk_path_, kSystemUid, kSystemGid, 0644));
2107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create the app user data.
2127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(service_->createAppData(
2137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
2147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_name_,
2157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kTestUserId,
2167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kAppDataFlags,
2177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kTestAppUid,
2187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            se_info_,
2197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kOSdkVersion,
2207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &ce_data_inode_).isOk());
2217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create a secondary dex file on CE storage
2237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        const char* volume_uuid_cstr = volume_uuid_ == nullptr ? nullptr : volume_uuid_->c_str();
2247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_private_dir_ce_ = create_data_user_ce_package_path(
2257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_ce_ = app_private_dir_ce_ + "/secondary_ce.jar";
2277d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, secondary_dex_ce_, kTestAppUid, kTestAppGid, 0600));
2287d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string app_private_dir_ce_link = create_data_user_ce_package_path_as_user_link(
2297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_ce_link_ = app_private_dir_ce_link + "/secondary_ce.jar";
2317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create a secondary dex file on DE storage.
2337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_private_dir_de_ = create_data_user_de_package_path(
2347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_de_ = app_private_dir_de_ + "/secondary_de.jar";
2367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, secondary_dex_de_, kTestAppUid, kTestAppGid, 0600));
2377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Fix app data uid.
2397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(service_->fixupAppData(volume_uuid_, kTestUserId).isOk());
2407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2427d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
24329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string GetSecondaryDexArtifact(const std::string& path, const std::string& type) {
2447d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string::size_type end = path.rfind('.');
2457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string::size_type start = path.rfind('/', end);
2467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        return path.substr(0, start) + "/oat/" + kRuntimeIsa + "/" +
2477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                path.substr(start + 1, end - start) + type;
2487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2497d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
25029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
2517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_be_compiled = true,
252023b22415ba9ce046f649817da27e40db8893451Andreas Gampe            /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1) {
253d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
254d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
255d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
2567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
2577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int32_t dexopt_needed = 0;  // does not matter;
2587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> out_path = nullptr;  // does not matter
2597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
2607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string compiler_filter = "speed-profile";
2617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
2627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
2637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool downgrade = false;
264570d398770a12613461408b767ae97b549393157David Brazdil        int32_t target_sdk_version = 0;  // default
265c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> profile_name_ptr = nullptr;
26662c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        std::unique_ptr<std::string> dm_path_ptr = nullptr;
2672efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle        std::unique_ptr<std::string> compilation_reason_ptr = nullptr;
268408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle
2697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->dexopt(path,
2707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 uid,
2717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 package_name_ptr,
2727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 kRuntimeIsa,
2737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dexopt_needed,
2747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 out_path,
2757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dex_flags,
2767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 compiler_filter,
2777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 volume_uuid_,
2787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 class_loader_context_ptr,
2797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 se_info_ptr,
280570d398770a12613461408b767ae97b549393157David Brazdil                                                 downgrade,
281408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 target_sdk_version,
28262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                                                 profile_name_ptr,
2832efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 dm_path_ptr,
2842efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 compilation_reason_ptr);
285f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
2867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_compiled ? 0 : -1;
28729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
28829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
28929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
2907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
2917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
2927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
293023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        if (binder_result != nullptr) {
294023b22415ba9ce046f649817da27e40db8893451Andreas Gampe            *binder_result = result;
295023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        }
2967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
2997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
300d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            int32_t uid = -1, std::string* package_override = nullptr) {
301d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
302d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
303d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
3047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::vector<std::string> isas;
3057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        isas.push_back(kRuntimeIsa);
3067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool out_secondary_dex_exists = false;
3077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->reconcileSecondaryDexFile(
3087d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            path,
3097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_override == nullptr ? package_name_ : *package_override,
3107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            uid,
3117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            isas,
3127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
3137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            storage_flag,
3147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &out_secondary_dex_exists);
3157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
316f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
3177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
3187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_deleted ? -1 : 0;
32029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
32129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
32229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
3237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
3247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
3257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
3267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
32729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
32829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
32929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
33029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, stat(file.c_str(), &st));
33129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(uid, st.st_uid);
33229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(gid, st.st_gid);
33329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(mode, st.st_mode);
33429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
335c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
336c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexOk(std::string compiler_filter,
337c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dex_flags,
338c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             const char* oat_dir,
339c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t uid,
340c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dexopt_needed,
341023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                             binder::Status* binder_result = nullptr,
34262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                             const char* dm_path = nullptr,
343c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             bool downgrade = false) {
344023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        CompilePrimaryDex(compiler_filter,
345023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dex_flags,
346023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          oat_dir,
347023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          uid,
348023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dexopt_needed,
349023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dm_path,
350023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          downgrade,
351023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          true,
352023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          binder_result);
353c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
354c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
355c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexFail(std::string compiler_filter,
356c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dex_flags,
357c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               const char* oat_dir,
358c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t uid,
359c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dexopt_needed,
360023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                               binder::Status* binder_result = nullptr,
36162c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                               const char* dm_path = nullptr,
362c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               bool downgrade = false) {
363023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        CompilePrimaryDex(compiler_filter,
364023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dex_flags,
365023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          oat_dir,
366023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          uid,
367023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dexopt_needed,
368023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          dm_path,
369023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          downgrade,
370023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          false,
371023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          binder_result);
372c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
373c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
374c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDex(std::string compiler_filter,
375c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dex_flags,
376c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           const char* oat_dir,
377c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t uid,
378c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dexopt_needed,
37962c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                           const char* dm_path,
380c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           bool downgrade,
381023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                           bool should_binder_call_succeed,
382023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                           /*out */ binder::Status* binder_result) {
383c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
384c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> out_path(
385c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                oat_dir == nullptr ? nullptr : new std::string(oat_dir));
386c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
387c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
388c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        int32_t target_sdk_version = 0;  // default
389c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
39062c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        std::unique_ptr<std::string> dm_path_ptr = nullptr;
39162c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        if (dm_path != nullptr) {
39262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle            dm_path_ptr.reset(new std::string(dm_path));
39362c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        }
3942efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle        std::unique_ptr<std::string> compilation_reason_ptr(new std::string("test-reason"));
395c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
396c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        bool prof_result;
397c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status prof_binder_result = service_->prepareAppProfile(
3981ebe77f1520fbbd7f633eef42c867fe79b672c1dJeff Sharkey                package_name_, kTestUserId, kTestAppId, *profile_name_ptr, apk_path_,
399c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                /*dex_metadata*/ nullptr, &prof_result);
400c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
401f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_TRUE(prof_binder_result.isOk()) << prof_binder_result.toString8().c_str();
402c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_TRUE(prof_result);
403c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
404c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status result = service_->dexopt(apk_path_,
405c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 uid,
406c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 package_name_ptr,
407c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 kRuntimeIsa,
408c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dexopt_needed,
409c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 out_path,
410c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dex_flags,
411c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 compiler_filter,
412c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 volume_uuid_,
413c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 class_loader_context_ptr,
414c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 se_info_ptr,
415c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 downgrade,
416c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 target_sdk_version,
41762c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                                                 profile_name_ptr,
4182efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 dm_path_ptr,
4192efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 compilation_reason_ptr);
420f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
421c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
422c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (!should_binder_call_succeed) {
423023b22415ba9ce046f649817da27e40db8893451Andreas Gampe            if (binder_result != nullptr) {
424023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                *binder_result = result;
425023b22415ba9ce046f649817da27e40db8893451Andreas Gampe            }
426c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return;
427c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
428c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        // Check the access to the compiler output.
429c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - speed-profile artifacts are not world-wide readable.
430c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - files are owned by the system uid.
431c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetPrimaryDexArtifact(oat_dir, apk_path_, "odex");
432c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
433c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
434c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
4355bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
4365bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
437c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(odex, kSystemUid, uid, mode);
438c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(vdex, kSystemUid, uid, mode);
439c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
4405bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        if (compiler_filter == "speed-profile") {
4415bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle            CheckFileAccess(art, kSystemUid, uid, mode);
4425bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        }
443023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        if (binder_result != nullptr) {
444023b22415ba9ce046f649817da27e40db8893451Andreas Gampe            *binder_result = result;
445023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        }
446c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
447c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
448c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    std::string GetPrimaryDexArtifact(const char* oat_dir,
449c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& dex_path,
450c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& type) {
451c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (oat_dir == nullptr) {
452c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string path = dex_path;
453c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            for (auto it = path.begin() + 1; it < path.end(); ++it) {
454c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                if (*it == '/') {
455c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    *it = '@';
456c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                }
457c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            }
458c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return android_data_dir + DALVIK_CACHE + '/' + kRuntimeIsa + "/" + path
459c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    + "@classes.dex";
460c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        } else {
461c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_end = dex_path.rfind('.');
462c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_start = dex_path.rfind('/');
463c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return std::string(oat_dir) + "/" + kRuntimeIsa + "/" +
464c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    dex_path.substr(name_start + 1, name_end - name_start) + type;
465c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
466c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
4677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
4687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4707d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCe) {
4717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCe";
47229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
4737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4767d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCeLink) {
4777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCeLink";
47829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
4797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4827d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDe) {
4837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDe";
48429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
4857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4887d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
4897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDoesNotExist";
4907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // If the file validates but does not exist we do not treat it as an error.
491023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    binder::Status status;
49229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
493023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        /*binder_ok*/ true,  /*compile_ok*/ false, &status);
494023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    EXPECT_STREQ(status.toString8().c_str(), "No error");
4957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4977d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
4987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryStorageValidationError";
499023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    binder::Status status;
50029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
501023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        /*binder_ok*/ false,  /*compile_ok*/ false, &status);
5023008bbefaa4719cbbf5aad6dc3f3934c50668da5Andreas Gampe    EXPECT_STREQ(status.toString8().c_str(),
5033008bbefaa4719cbbf5aad6dc3f3934c50668da5Andreas Gampe                 "Status(-8): '-1: Dexoptanalyzer path validation failed'");
5047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5067d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
5077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
508023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    binder::Status status;
50929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
510023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        /*binder_ok*/ false,  /*compile_ok*/ false, &status);
5113008bbefaa4719cbbf5aad6dc3f3934c50668da5Andreas Gampe    EXPECT_STREQ(status.toString8().c_str(),
5123008bbefaa4719cbbf5aad6dc3f3934c50668da5Andreas Gampe                 "Status(-8): '-1: Dexoptanalyzer path validation failed'");
5137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5157d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
5167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
517023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    binder::Status status;
51829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
519023b22415ba9ce046f649817da27e40db8893451Andreas Gampe        /*binder_ok*/ false,  /*compile_ok*/ false, &status, kSystemUid);
5203008bbefaa4719cbbf5aad6dc3f3934c50668da5Andreas Gampe    EXPECT_STREQ(status.toString8().c_str(), "Status(-8): '-1: Dexoptanalyzer open zip failed'");
5217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
523c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryPublic) {
524c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryPublic";
525c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
526c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
527c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
528c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
529c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
530c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
531c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
5325bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin JuravleTEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
5335bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
534023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    binder::Status status;
5355bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    CompilePrimaryDexFail("awesome-filter",
5365bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
5375bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          app_oat_dir_.c_str(),
5385bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          kTestAppGid,
539023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          DEX2OAT_FROM_SCRATCH,
540023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                          &status);
541023b22415ba9ce046f649817da27e40db8893451Andreas Gampe    EXPECT_STREQ(status.toString8().c_str(),
542023b22415ba9ce046f649817da27e40db8893451Andreas Gampe                 "Status(-8): \'256: Dex2oat invocation for "
543fa2dadd64b42c6c24d1cda007ce59a33696517e2Andreas Gampe                 "/data/app/com.installd.test.dexopt/base.jar failed: unspecified dex2oat error'");
5445bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle}
5455bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle
546c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
547c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfileNonPublic";
548c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
5494f1ad408b8b830e2b8dc852f65031e504b036a36Mathieu Chartier                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_GENERATE_APP_IMAGE,
550c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
551c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
552c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
553c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
554c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
555c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
556c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfilePublic";
5575bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    CompilePrimaryDexOk("speed-profile",
5584f1ad408b8b830e2b8dc852f65031e504b036a36Mathieu Chartier                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC |
5594f1ad408b8b830e2b8dc852f65031e504b036a36Mathieu Chartier                                DEXOPT_GENERATE_APP_IMAGE,
560c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
561c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
562c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
563c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
564c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
565c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
566c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryBackgroundOk";
567c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
5684f1ad408b8b830e2b8dc852f65031e504b036a36Mathieu Chartier                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
5694f1ad408b8b830e2b8dc852f65031e504b036a36Mathieu Chartier                                DEXOPT_GENERATE_APP_IMAGE,
570c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
571c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
572c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
573c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
574c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
575c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravleclass PrimaryDexReCompilationTest : public DexoptTest {
576c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  public:
577c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void SetUp() {
578c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::SetUp();
579c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CompilePrimaryDexOk("verify",
580c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
581c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            app_oat_dir_.c_str(),
582c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            kTestAppGid,
583c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEX2OAT_FROM_SCRATCH);
584c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetSecondaryDexArtifact(apk_path_, "odex");
585c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetSecondaryDexArtifact(apk_path_, "vdex");
586c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
587c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(open(odex.c_str(), O_RDONLY));
588c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(open(vdex.c_str(), O_RDONLY));
589c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
590c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
591c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void TearDown() {
592c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(-1);
593c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(-1);
594c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::TearDown();
595c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
596c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
597c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  protected:
598c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_odex_fd_;
599c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_vdex_fd_;
600c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle};
601c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
602c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(PrimaryDexReCompilationTest, DexoptPrimaryUpdateInPlaceVdex) {
603c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryUpdateInPlaceVdex";
604c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
605c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
606c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
607c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
608c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
609c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FOR_BOOT_IMAGE);
610c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
6117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleclass ReconcileTest : public DexoptTest {
6137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
6147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        DexoptTest::SetUp();
61529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
6167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
61729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
6187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
6197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
6207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
6217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6227d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
6237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeExists";
6247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
6267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6277d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6287d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
6297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeLinkExists";
6307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
6317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
6327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6347d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
6357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeExists";
6367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
6377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
6387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6407d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
6417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
6427d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    run_cmd("rm -rf " + secondary_dex_de_);
6437d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
6447d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
6457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6477d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
6487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Validation errors will not clean the odex/vdex/art files but will mark
6497d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // the file as non existent so that the PM knows it should purge it from its
6507d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // records.
6517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryStorageValidationError";
6527d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
6537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
6547d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6567d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
6577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
6587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Attempt to reconcile the dex files of the test app from a different app.
6597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string another_app = "another.app";
6607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
6627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6647d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
6657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
6667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
6687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
67029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleclass ProfileTest : public DexoptTest {
67129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle  protected:
67229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string cur_profile_;
67329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string ref_profile_;
67429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string snap_profile_;
67529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
676824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    static constexpr const char* kPrimaryProfile = "primary.prof";
677824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
67829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    virtual void SetUp() {
67929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        DexoptTest::SetUp();
68029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        cur_profile_ = create_current_profile_path(
681824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
682824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
683824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                /*is_secondary_dex*/ false);
684824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
68529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
68629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
687824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
688824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            int32_t num_dex) {
689824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
690824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
691824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile=" + path);
69229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chmod(path.c_str(), mode);
69329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chown(path.c_str(), uid, gid);
69429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
69529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
69629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void SetupProfiles(bool setup_ref) {
69729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
69829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (setup_ref) {
699824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
70029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
70129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
70229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
703c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    void createProfileSnapshot(int32_t appid, const std::string& package_name,
704c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle            bool expected_result) {
70529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result;
706c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
7070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                appid, package_name, kPrimaryProfile, apk_path_, &result);
708f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_TRUE(binder_result.isOk()) << binder_result.toString8().c_str();
70929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(expected_result, result);
71029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
71129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!expected_result) {
71229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // Do not check the files if we expect to fail.
71329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return;
71429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
71529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
71629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
71729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
71829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
71929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
72029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string expected_profile_content = snap_profile_ + ".expected";
72129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("rm -f " + expected_profile_content);
72229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("touch " + expected_profile_content);
72329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
72429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --profile-file=" + ref_profile_ +
72540b5f46cafa02d48d58b3d5a458df5aceaba52e9Calin Juravle                " --reference-profile-file=" + expected_profile_content +
72640b5f46cafa02d48d58b3d5a458df5aceaba52e9Calin Juravle                " --apk=" + apk_path_);
72729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
72829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
72929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
73029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        pid_t pid = fork();
73129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (pid == 0) {
73229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            /* child */
73329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            TransitionToSystemServer();
73429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
73529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // System server should be able to open the the spanshot.
73629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
73729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
73829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            _exit(0);
73929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
74029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        /* parent */
74129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
74229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
74329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
744408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    void mergePackageProfiles(const std::string& package_name,
745408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              const std::string& code_path,
746408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              bool expected_result) {
747824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        bool result;
748824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        binder::Status binder_result = service_->mergeProfiles(
749408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                kTestAppUid, package_name, code_path, &result);
750f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_TRUE(binder_result.isOk()) << binder_result.toString8().c_str();
751824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_EQ(expected_result, result);
752824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
753824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        if (!expected_result) {
754824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            // Do not check the files if we expect to fail.
755824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            return;
756824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        }
757824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
758824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
759824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
760824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
761824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
762824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        std::string ref_profile_content = ref_profile_ + ".expected";
763824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("rm -f " + ref_profile_content);
764824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("touch " + ref_profile_content);
765824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
766824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --profile-file=" + ref_profile_ +
767824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --reference-profile-file=" + ref_profile_content);
768824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
769824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
770824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    }
771824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
772c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // TODO(calin): add dex metadata tests once the ART change is merged.
773c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
774c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            bool expected_result) {
775c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        bool result;
776c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        binder::Status binder_result = service_->prepareAppProfile(
7771ebe77f1520fbbd7f633eef42c867fe79b672c1dJeff Sharkey                package_name, kTestUserId, kTestAppId, profile_name, apk_path_,
778c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                /*dex_metadata*/ nullptr, &result);
779f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe        ASSERT_TRUE(binder_result.isOk()) << binder_result.toString8().c_str();
780c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(expected_result, result);
781c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
782c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        if (!expected_result) {
783c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            // Do not check the files if we expect to fail.
784c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            return;
785c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        }
786c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
787c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_cur_prof = create_current_profile_path(
788c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
789c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_ref_profile = create_reference_profile_path(package_name,
790c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                profile_name, /*is_secondary_dex*/ false);
791c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
792c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Check that we created the current profile.
793c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
794c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
795c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Without dex metadata we don't generate a reference profile.
796c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
797c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    }
798c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
7990d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
80029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void TransitionToSystemServer() {
80129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
80229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        int32_t res = selinux_android_setcontext(
80329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                kSystemUid, true, se_info_.c_str(), "system_server");
80429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
80529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
80629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool AreFilesEqual(const std::string& file1, const std::string& file2) {
80829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content1;
80929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content2;
81029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
81129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file1, &content1)) return false;
81229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file2, &content2)) return false;
81329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return content1 == content2;
81429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
81529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
81629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
81729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        unique_fd fd(open(file.c_str(), O_RDONLY));
81829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fd < 0) {
81929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to open " << file;
82029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
82129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
82229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
82329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fstat(fd, &st) != 0) {
82429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to stat " << file;
82529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
82629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
82729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        content->resize(st.st_size);
82829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result = ReadFully(fd, content->data(), content->size());
82929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!result) {
83029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to read " << file;
83129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
83229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return result;
83329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
83429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle};
83529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
83629591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOk) {
83729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOk";
83829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
83929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
840c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
84129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
84229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
84329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// The reference profile is created on the fly. We need to be able to
84429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// snapshot without one.
84529591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
84629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOkNoReference";
84729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
84829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ false);
849c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
85029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
85129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
85229591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
85329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotFailWrongPackage";
85429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
85529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
856c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
85729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
85829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
85929591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
86029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotDestroySnapshot";
86129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
86229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
863c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
86429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
865824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    binder::Status binder_result = service_->destroyProfileSnapshot(package_name_, kPrimaryProfile);
866f6a93b1969c18d92e3c218ed7856cb5d9c872fcdAndreas Gampe    ASSERT_TRUE(binder_result.isOk()) << binder_result.toString8().c_str();
86729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    struct stat st;
86829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
86929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(ENOENT, errno);
87029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
87129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
872824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOk) {
873824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOk";
874824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
875824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
876408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
877824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
878824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
879824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// The reference profile is created on the fly. We need to be able to
880824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// merge without one.
881824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOkNoReference) {
882824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOkNoReference";
883824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
884824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ false);
885408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
886824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
887824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
888824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
889824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeFailWrongPackage";
890824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
891824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
892408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
893824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
894824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
895d2affb8601630fe682b03407fc907f2439ff5370Calin JuravleTEST_F(ProfileTest, ProfileDirOk) {
896d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    LOG(INFO) << "ProfileDirOk";
897d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
898d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
899d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            kTestUserId, package_name_);
900d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
901824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
902d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
903d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
904d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
9056f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
9066f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle}
9076f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
9086f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// Verify that the profile directories are fixed up during an upgrade.
9096f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// (The reference profile directory is prepared lazily).
9106f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin JuravleTEST_F(ProfileTest, ProfileDirOkAfterFixup) {
9116f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    LOG(INFO) << "ProfileDirOkAfterFixup";
9126f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
9136f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
9146f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId, package_name_);
9156f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
916824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
9176f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
9186f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
9196f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
9206f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
9216f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
9226f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
9236f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Run createAppData again which will offer to fix-up the profile directories.
9246f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_TRUE(service_->createAppData(
9256f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            volume_uuid_,
9266f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            package_name_,
9276f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId,
9286f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kAppDataFlags,
9296f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestAppUid,
9306f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            se_info_,
9316f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kOSdkVersion,
9326f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            &ce_data_inode_).isOk());
9336f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
9346f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Check the file access.
9356f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
9366f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
937d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle}
938d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
939c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareOk) {
940c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareOk";
941c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
942c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
943c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
944c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
945c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailInvalidPackage";
946c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
947c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
948c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
949c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
950c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
951c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    SetupProfiles(/*setup_ref*/ false);
952c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // Change the uid on the profile to trigger a failure.
953c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
954c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
955c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
956c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
9570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9580d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravleclass BootProfileTest : public ProfileTest {
9590d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  public:
9600d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void setup() {
9610d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::SetUp();
9620d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        intial_android_profiles_dir = android_profiles_dir;
9630d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9640d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9650d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void TearDown() {
9660d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = intial_android_profiles_dir;
9670d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::TearDown();
9680d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9690d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9700d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void UpdateAndroidProfilesDir(const std::string& profile_dir) {
9710d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = profile_dir;
9720d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // We need to create the reference profile directory in the new profile dir.
9730d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        run_cmd("mkdir -p " + profile_dir + "/ref");
9740d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9750d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9760d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
9770d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        bool result;
9780d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
9790d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                -1, "android", "android.prof", classpath, &result);
9800d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(binder_result.isOk());
9810d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_EQ(expected_result, result);
9820d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9830d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (!expected_result) {
9840d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // Do not check the files if we expect to fail.
9850d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            return;
9860d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
9870d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9880d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // Check that the snapshot was created with he expected access flags.
9890d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
9900d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
9910d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9920d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        pid_t pid = fork();
9930d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (pid == 0) {
9940d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            /* child */
9950d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            TransitionToSystemServer();
9960d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9970d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // System server should be able to open the snapshot.
9980d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
9990d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
10000d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            _exit(0);
10010d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
10020d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        /* parent */
10030d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
10040d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
10050d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
10060d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string intial_android_profiles_dir;
10070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle};
10080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10090d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOk) {
10100d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOk";
10110d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
10120d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
10130d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
10140d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10150d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10160d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
10170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
10180d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10190d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
10200d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10210d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10220d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
10230d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
10240d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
10250d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
10260d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10270d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
10280d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Still, this is not a failure case.
10290d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_apk_dir_);
10300d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
10310d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10320d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10330d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle// Verify that profile collection.
10340d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, CollectProfiles) {
10350d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "CollectProfiles";
10360d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10370d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some profile directories mimicking the real profile structure.
10380d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
10390d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
10400d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
10410d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create an empty profile.
10420d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
10430d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create a random file.
10440d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
10450d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10460d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some non-empty profiles.
10470d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
10480d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + current_prof);
10490d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
10500d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + ref_prof);
10510d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10520d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
10530d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10540d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::vector<std::string> profiles;
10550d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    collect_profiles(&profiles);
10560d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Only two profiles should be in the output.
10580d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_EQ(2u, profiles.size());
10590d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
10600d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
10610d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10620d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace installd
10647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace android
1065