installd_dexopt_test.cpp revision c4f6a0b6333980a069900e2afff2c755f30fe09c
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,
252d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            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;
266408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle
2677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->dexopt(path,
2687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 uid,
2697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 package_name_ptr,
2707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 kRuntimeIsa,
2717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dexopt_needed,
2727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 out_path,
2737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dex_flags,
2747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 compiler_filter,
2757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 volume_uuid_,
2767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 class_loader_context_ptr,
2777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 se_info_ptr,
278570d398770a12613461408b767ae97b549393157David Brazdil                                                 downgrade,
279408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 target_sdk_version,
280408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 profile_name_ptr);
2817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
2827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_compiled ? 0 : -1;
28329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
28429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
28529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
2867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
2877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
2887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
2897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
2927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
293d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            int32_t uid = -1, std::string* package_override = nullptr) {
294d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
295d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
296d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
2977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::vector<std::string> isas;
2987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        isas.push_back(kRuntimeIsa);
2997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool out_secondary_dex_exists = false;
3007d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->reconcileSecondaryDexFile(
3017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            path,
3027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_override == nullptr ? package_name_ : *package_override,
3037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            uid,
3047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            isas,
3057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
3067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            storage_flag,
3077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &out_secondary_dex_exists);
3087d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
3107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
3117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_deleted ? -1 : 0;
31329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
31429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
31529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
3167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
3177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
3187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
3197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
32029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
32129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
32229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
32329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, stat(file.c_str(), &st));
32429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(uid, st.st_uid);
32529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(gid, st.st_gid);
32629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(mode, st.st_mode);
32729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
328c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
329c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexOk(std::string compiler_filter,
330c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dex_flags,
331c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             const char* oat_dir,
332c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t uid,
333c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dexopt_needed,
334c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             bool downgrade = false) {
335c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        return CompilePrimaryDex(
336c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                compiler_filter, dex_flags, oat_dir, uid, dexopt_needed, downgrade, true);
337c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
338c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
339c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexFail(std::string compiler_filter,
340c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dex_flags,
341c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               const char* oat_dir,
342c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t uid,
343c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dexopt_needed,
344c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               bool downgrade = false) {
345c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        return CompilePrimaryDex(
346c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                compiler_filter, dex_flags, oat_dir, uid, dexopt_needed, downgrade, false);
347c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
348c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
349c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDex(std::string compiler_filter,
350c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dex_flags,
351c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           const char* oat_dir,
352c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t uid,
353c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dexopt_needed,
354c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           bool downgrade,
355c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           bool should_binder_call_succeed) {
356c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
357c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> out_path(
358c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                oat_dir == nullptr ? nullptr : new std::string(oat_dir));
359c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
360c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
361c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        int32_t target_sdk_version = 0;  // default
362c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
363c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
364c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        bool prof_result;
365c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status prof_binder_result = service_->prepareAppProfile(
366c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                package_name_, kTestUserId, kTestAppId, *profile_name_ptr, /*code path*/ "base.apk",
367c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                /*dex_metadata*/ nullptr, &prof_result);
368c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
369c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_TRUE(prof_binder_result.isOk());
370c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_TRUE(prof_result);
371c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
372c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status result = service_->dexopt(apk_path_,
373c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 uid,
374c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 package_name_ptr,
375c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 kRuntimeIsa,
376c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dexopt_needed,
377c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 out_path,
378c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dex_flags,
379c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 compiler_filter,
380c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 volume_uuid_,
381c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 class_loader_context_ptr,
382c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 se_info_ptr,
383c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 downgrade,
384c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 target_sdk_version,
385c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 profile_name_ptr);
386c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
387c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
388c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (!should_binder_call_succeed) {
389c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return;
390c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
391c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        // Check the access to the compiler output.
392c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - speed-profile artifacts are not world-wide readable.
393c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - files are owned by the system uid.
394c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetPrimaryDexArtifact(oat_dir, apk_path_, "odex");
395c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
396c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
397c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
398c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        mode_t mode = S_IFREG | (compiler_filter == "speed-profile" ? 0640 : 0644);
399c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(odex, kSystemUid, uid, mode);
400c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(vdex, kSystemUid, uid, mode);
401c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(odex, kSystemUid, uid, mode);
402c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
403c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        // empty profiles do not generate an image.
404c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        // todo: add tests with non-empty profiles.
405c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        struct stat st;
406c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_EQ(-1, stat(art.c_str(), &st));
407c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
408c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
409c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    std::string GetPrimaryDexArtifact(const char* oat_dir,
410c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& dex_path,
411c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& type) {
412c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (oat_dir == nullptr) {
413c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string path = dex_path;
414c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            for (auto it = path.begin() + 1; it < path.end(); ++it) {
415c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                if (*it == '/') {
416c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    *it = '@';
417c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                }
418c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            }
419c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return android_data_dir + DALVIK_CACHE + '/' + kRuntimeIsa + "/" + path
420c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    + "@classes.dex";
421c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        } else {
422c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_end = dex_path.rfind('.');
423c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_start = dex_path.rfind('/');
424c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return std::string(oat_dir) + "/" + kRuntimeIsa + "/" +
425c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    dex_path.substr(name_start + 1, name_end - name_start) + type;
426c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
427c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
4287d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
4297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4317d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCe) {
4327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCe";
43329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
4347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4377d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCeLink) {
4387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCeLink";
43929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
4407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4427d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4437d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDe) {
4447d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDe";
44529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
4467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4497d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
4507d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDoesNotExist";
4517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // If the file validates but does not exist we do not treat it as an error.
45229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
4537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true,  /*compile_ok*/ false);
4547d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4567d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
4577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryStorageValidationError";
45829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
4597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
4607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4627d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
4637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
46429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
4657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
4667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4687d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
4697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
47029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
4717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false, kSystemUid);
4727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
474c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryPublic) {
475c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryPublic";
476c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
477c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
478c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
479c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
480c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
481c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
482c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
483c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
484c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfileNonPublic";
485c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
486c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_BOOTCOMPLETE,
487c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
488c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
489c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
490c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
491c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
492c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
493c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfilePublic";
494c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
495c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
496c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
497c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
498c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
499c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
500c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
501c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
502c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryBackgroundOk";
503c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
504c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_IDLE_BACKGROUND_JOB,
505c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
506c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
507c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
508c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
509c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
510c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
511c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
512c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexFail("awesome-filter",
513c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                          DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
514c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                          app_oat_dir_.c_str(),
515c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                          kTestAppGid,
516c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                          DEX2OAT_FROM_SCRATCH);
517c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
518c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
519c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravleclass PrimaryDexReCompilationTest : public DexoptTest {
520c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  public:
521c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void SetUp() {
522c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::SetUp();
523c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CompilePrimaryDexOk("verify",
524c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
525c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            app_oat_dir_.c_str(),
526c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            kTestAppGid,
527c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEX2OAT_FROM_SCRATCH);
528c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetSecondaryDexArtifact(apk_path_, "odex");
529c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetSecondaryDexArtifact(apk_path_, "vdex");
530c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
531c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(open(odex.c_str(), O_RDONLY));
532c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(open(vdex.c_str(), O_RDONLY));
533c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
534c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
535c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void TearDown() {
536c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(-1);
537c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(-1);
538c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::TearDown();
539c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
540c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
541c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  protected:
542c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_odex_fd_;
543c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_vdex_fd_;
544c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle};
545c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
546c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(PrimaryDexReCompilationTest, DexoptPrimaryUpdateInPlaceVdex) {
547c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryUpdateInPlaceVdex";
548c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
549c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
550c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
551c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
552c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
553c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FOR_BOOT_IMAGE);
554c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
5557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleclass ReconcileTest : public DexoptTest {
5577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
5587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        DexoptTest::SetUp();
55929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
5607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
56129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
5627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
5637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
5647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
5657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5667d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
5677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeExists";
5687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
5697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5727d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
5737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeLinkExists";
5747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
5757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5787d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
5797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeExists";
5807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
5817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5847d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
5857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
5867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    run_cmd("rm -rf " + secondary_dex_de_);
5877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
5887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
5897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5917d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
5927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Validation errors will not clean the odex/vdex/art files but will mark
5937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // the file as non existent so that the PM knows it should purge it from its
5947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // records.
5957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryStorageValidationError";
5967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
5977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
5987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6007d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
6017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
6027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Attempt to reconcile the dex files of the test app from a different app.
6037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string another_app = "another.app";
6047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
6067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6087d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
6097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
6107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
6127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
61429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleclass ProfileTest : public DexoptTest {
61529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle  protected:
61629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string cur_profile_;
61729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string ref_profile_;
61829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string snap_profile_;
61929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
620824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    static constexpr const char* kPrimaryProfile = "primary.prof";
621824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
62229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    virtual void SetUp() {
62329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        DexoptTest::SetUp();
62429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        cur_profile_ = create_current_profile_path(
625824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
626824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
627824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                /*is_secondary_dex*/ false);
628824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
62929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
63029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
631824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
632824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            int32_t num_dex) {
633824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
634824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
635824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile=" + path);
63629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chmod(path.c_str(), mode);
63729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chown(path.c_str(), uid, gid);
63829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
63929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
64029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void SetupProfiles(bool setup_ref) {
64129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
64229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (setup_ref) {
643824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
64429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
64529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
64629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
647c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    void createProfileSnapshot(int32_t appid, const std::string& package_name,
648c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle            bool expected_result) {
64929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result;
650c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
6510d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                appid, package_name, kPrimaryProfile, apk_path_, &result);
65229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(binder_result.isOk());
65329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(expected_result, result);
65429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
65529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!expected_result) {
65629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // Do not check the files if we expect to fail.
65729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return;
65829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
65929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
66029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
66129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
66229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
66329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
66429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string expected_profile_content = snap_profile_ + ".expected";
66529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("rm -f " + expected_profile_content);
66629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("touch " + expected_profile_content);
66729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
66829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --profile-file=" + ref_profile_ +
66929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --reference-profile-file=" + expected_profile_content);
67029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
67129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
67229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
67329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        pid_t pid = fork();
67429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (pid == 0) {
67529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            /* child */
67629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            TransitionToSystemServer();
67729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
67829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // System server should be able to open the the spanshot.
67929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
68029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
68129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            _exit(0);
68229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
68329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        /* parent */
68429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
68529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
68629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
687408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    void mergePackageProfiles(const std::string& package_name,
688408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              const std::string& code_path,
689408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              bool expected_result) {
690824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        bool result;
691824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        binder::Status binder_result = service_->mergeProfiles(
692408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                kTestAppUid, package_name, code_path, &result);
693824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(binder_result.isOk());
694824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_EQ(expected_result, result);
695824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
696824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        if (!expected_result) {
697824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            // Do not check the files if we expect to fail.
698824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            return;
699824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        }
700824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
701824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
702824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
703824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
704824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
705824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        std::string ref_profile_content = ref_profile_ + ".expected";
706824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("rm -f " + ref_profile_content);
707824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("touch " + ref_profile_content);
708824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
709824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --profile-file=" + ref_profile_ +
710824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --reference-profile-file=" + ref_profile_content);
711824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
712824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
713824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    }
714824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
715c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // TODO(calin): add dex metadata tests once the ART change is merged.
716c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
717c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            bool expected_result) {
718c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        bool result;
719c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        binder::Status binder_result = service_->prepareAppProfile(
720c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                package_name, kTestUserId, kTestAppId, profile_name, /*code path*/ "base.apk",
721c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                /*dex_metadata*/ nullptr, &result);
722c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_TRUE(binder_result.isOk());
723c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(expected_result, result);
724c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
725c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        if (!expected_result) {
726c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            // Do not check the files if we expect to fail.
727c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            return;
728c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        }
729c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
730c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_cur_prof = create_current_profile_path(
731c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
732c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_ref_profile = create_reference_profile_path(package_name,
733c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                profile_name, /*is_secondary_dex*/ false);
734c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
735c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Check that we created the current profile.
736c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
737c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
738c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Without dex metadata we don't generate a reference profile.
739c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
740c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    }
741c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
7420d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
74329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void TransitionToSystemServer() {
74429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
74529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        int32_t res = selinux_android_setcontext(
74629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                kSystemUid, true, se_info_.c_str(), "system_server");
74729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
74829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
74929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
75029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool AreFilesEqual(const std::string& file1, const std::string& file2) {
75129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content1;
75229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content2;
75329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
75429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file1, &content1)) return false;
75529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file2, &content2)) return false;
75629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return content1 == content2;
75729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
75829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
75929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
76029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        unique_fd fd(open(file.c_str(), O_RDONLY));
76129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fd < 0) {
76229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to open " << file;
76329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
76429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
76529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
76629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fstat(fd, &st) != 0) {
76729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to stat " << file;
76829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
76929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
77029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        content->resize(st.st_size);
77129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result = ReadFully(fd, content->data(), content->size());
77229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!result) {
77329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to read " << file;
77429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
77529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return result;
77629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
77729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle};
77829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
77929591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOk) {
78029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOk";
78129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
78229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
783c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
78429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
78529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
78629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// The reference profile is created on the fly. We need to be able to
78729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// snapshot without one.
78829591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
78929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOkNoReference";
79029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
79129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ false);
792c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
79329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
79429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
79529591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
79629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotFailWrongPackage";
79729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
79829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
799c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
80029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
80129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80229591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
80329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotDestroySnapshot";
80429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
806c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
80729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
808824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    binder::Status binder_result = service_->destroyProfileSnapshot(package_name_, kPrimaryProfile);
80929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_TRUE(binder_result.isOk());
81029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    struct stat st;
81129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
81229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(ENOENT, errno);
81329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
81429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
815824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOk) {
816824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOk";
817824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
818824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
819408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
820824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
821824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
822824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// The reference profile is created on the fly. We need to be able to
823824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// merge without one.
824824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOkNoReference) {
825824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOkNoReference";
826824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
827824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ false);
828408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
829824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
830824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
831824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
832824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeFailWrongPackage";
833824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
834824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
835408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
836824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
837824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
838d2affb8601630fe682b03407fc907f2439ff5370Calin JuravleTEST_F(ProfileTest, ProfileDirOk) {
839d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    LOG(INFO) << "ProfileDirOk";
840d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
841d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
842d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            kTestUserId, package_name_);
843d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
844824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
845d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
846d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
847d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
8486f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
8496f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle}
8506f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8516f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// Verify that the profile directories are fixed up during an upgrade.
8526f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// (The reference profile directory is prepared lazily).
8536f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin JuravleTEST_F(ProfileTest, ProfileDirOkAfterFixup) {
8546f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    LOG(INFO) << "ProfileDirOkAfterFixup";
8556f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8566f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
8576f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId, package_name_);
8586f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
859824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
8606f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
8616f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8626f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
8636f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
8646f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
8656f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8666f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Run createAppData again which will offer to fix-up the profile directories.
8676f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_TRUE(service_->createAppData(
8686f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            volume_uuid_,
8696f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            package_name_,
8706f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId,
8716f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kAppDataFlags,
8726f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestAppUid,
8736f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            se_info_,
8746f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kOSdkVersion,
8756f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            &ce_data_inode_).isOk());
8766f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8776f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Check the file access.
8786f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
8796f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
880d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle}
881d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
882c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareOk) {
883c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareOk";
884c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
885c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
886c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
887c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
888c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailInvalidPackage";
889c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
890c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
891c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
892c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
893c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
894c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    SetupProfiles(/*setup_ref*/ false);
895c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // Change the uid on the profile to trigger a failure.
896c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
897c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
898c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
899c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
9000d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9010d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravleclass BootProfileTest : public ProfileTest {
9020d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  public:
9030d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void setup() {
9040d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::SetUp();
9050d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        intial_android_profiles_dir = android_profiles_dir;
9060d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void TearDown() {
9090d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = intial_android_profiles_dir;
9100d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::TearDown();
9110d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9120d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9130d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void UpdateAndroidProfilesDir(const std::string& profile_dir) {
9140d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = profile_dir;
9150d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // We need to create the reference profile directory in the new profile dir.
9160d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        run_cmd("mkdir -p " + profile_dir + "/ref");
9170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9180d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9190d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
9200d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        bool result;
9210d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
9220d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                -1, "android", "android.prof", classpath, &result);
9230d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(binder_result.isOk());
9240d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_EQ(expected_result, result);
9250d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9260d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (!expected_result) {
9270d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // Do not check the files if we expect to fail.
9280d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            return;
9290d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
9300d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9310d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // Check that the snapshot was created with he expected access flags.
9320d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
9330d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
9340d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9350d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        pid_t pid = fork();
9360d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (pid == 0) {
9370d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            /* child */
9380d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            TransitionToSystemServer();
9390d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9400d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // System server should be able to open the snapshot.
9410d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
9420d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
9430d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            _exit(0);
9440d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
9450d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        /* parent */
9460d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
9470d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9480d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
9490d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string intial_android_profiles_dir;
9500d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle};
9510d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9520d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOk) {
9530d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOk";
9540d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
9550d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
9560d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
9570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9580d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9590d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
9600d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
9610d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9620d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
9630d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9640d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9650d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
9660d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
9670d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
9680d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
9690d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9700d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
9710d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Still, this is not a failure case.
9720d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_apk_dir_);
9730d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
9740d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9750d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9760d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle// Verify that profile collection.
9770d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, CollectProfiles) {
9780d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "CollectProfiles";
9790d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9800d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some profile directories mimicking the real profile structure.
9810d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
9820d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
9830d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
9840d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create an empty profile.
9850d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
9860d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create a random file.
9870d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
9880d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9890d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some non-empty profiles.
9900d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
9910d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + current_prof);
9920d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
9930d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + ref_prof);
9940d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9950d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
9960d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9970d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::vector<std::string> profiles;
9980d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    collect_profiles(&profiles);
9990d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10000d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Only two profiles should be in the output.
10010d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_EQ(2u, profiles.size());
10020d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
10030d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
10040d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10050d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace installd
10077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace android
1008