installd_dexopt_test.cpp revision 2efc402a934d4d4d755d91d8bef5fdc3192084c3
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;
26662c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        std::unique_ptr<std::string> dm_path_ptr = nullptr;
2672efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle        std::unique_ptr<std::string> compilation_reason_ptr = nullptr;
268408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle
2697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->dexopt(path,
2707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 uid,
2717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 package_name_ptr,
2727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 kRuntimeIsa,
2737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dexopt_needed,
2747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 out_path,
2757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dex_flags,
2767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 compiler_filter,
2777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 volume_uuid_,
2787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 class_loader_context_ptr,
2797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 se_info_ptr,
280570d398770a12613461408b767ae97b549393157David Brazdil                                                 downgrade,
281408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 target_sdk_version,
28262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                                                 profile_name_ptr,
2832efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 dm_path_ptr,
2842efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 compilation_reason_ptr);
2857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
2867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_compiled ? 0 : -1;
28729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
28829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
28929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
2907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
2917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
2927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
2937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
2967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
297d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            int32_t uid = -1, std::string* package_override = nullptr) {
298d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
299d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
300d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
3017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::vector<std::string> isas;
3027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        isas.push_back(kRuntimeIsa);
3037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool out_secondary_dex_exists = false;
3047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->reconcileSecondaryDexFile(
3057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            path,
3067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_override == nullptr ? package_name_ : *package_override,
3077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            uid,
3087d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            isas,
3097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
3107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            storage_flag,
3117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &out_secondary_dex_exists);
3127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
3147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
3157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_deleted ? -1 : 0;
31729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
31829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
31929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
3207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
3217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
3227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
3237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
32429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
32529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
32629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
32729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, stat(file.c_str(), &st));
32829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(uid, st.st_uid);
32929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(gid, st.st_gid);
33029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(mode, st.st_mode);
33129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
332c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
333c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexOk(std::string compiler_filter,
334c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dex_flags,
335c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             const char* oat_dir,
336c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t uid,
337c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             int32_t dexopt_needed,
33862c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                             const char* dm_path = nullptr,
339c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                             bool downgrade = false) {
340c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        return CompilePrimaryDex(
34162c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                compiler_filter, dex_flags, oat_dir, uid, dexopt_needed, dm_path, downgrade, true);
342c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
343c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
344c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDexFail(std::string compiler_filter,
345c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dex_flags,
346c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               const char* oat_dir,
347c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t uid,
348c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               int32_t dexopt_needed,
34962c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                               const char* dm_path = nullptr,
350c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                               bool downgrade = false) {
351c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        return CompilePrimaryDex(
35262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                compiler_filter, dex_flags, oat_dir, uid, dexopt_needed, dm_path, downgrade, false);
353c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
354c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
355c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    void CompilePrimaryDex(std::string compiler_filter,
356c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dex_flags,
357c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           const char* oat_dir,
358c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t uid,
359c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           int32_t dexopt_needed,
36062c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                           const char* dm_path,
361c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           bool downgrade,
362c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                           bool should_binder_call_succeed) {
363c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
364c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> out_path(
365c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                oat_dir == nullptr ? nullptr : new std::string(oat_dir));
366c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
367c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
368c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        int32_t target_sdk_version = 0;  // default
369c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
37062c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        std::unique_ptr<std::string> dm_path_ptr = nullptr;
37162c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        if (dm_path != nullptr) {
37262c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle            dm_path_ptr.reset(new std::string(dm_path));
37362c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle        }
3742efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle        std::unique_ptr<std::string> compilation_reason_ptr(new std::string("test-reason"));
375c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
376c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        bool prof_result;
377c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status prof_binder_result = service_->prepareAppProfile(
378c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                package_name_, kTestUserId, kTestAppId, *profile_name_ptr, /*code path*/ "base.apk",
379c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                /*dex_metadata*/ nullptr, &prof_result);
380c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
381c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_TRUE(prof_binder_result.isOk());
382c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_TRUE(prof_result);
383c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
384c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        binder::Status result = service_->dexopt(apk_path_,
385c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 uid,
386c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 package_name_ptr,
387c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 kRuntimeIsa,
388c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dexopt_needed,
389c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 out_path,
390c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 dex_flags,
391c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 compiler_filter,
392c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 volume_uuid_,
393c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 class_loader_context_ptr,
394c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 se_info_ptr,
395c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 downgrade,
396c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                                 target_sdk_version,
39762c5a373fccf94cb3c125514aaff033d36fc101eCalin Juravle                                                 profile_name_ptr,
3982efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 dm_path_ptr,
3992efc402a934d4d4d755d91d8bef5fdc3192084c3Calin Juravle                                                 compilation_reason_ptr);
400c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
401c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
402c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (!should_binder_call_succeed) {
403c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return;
404c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
405c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        // Check the access to the compiler output.
406c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - speed-profile artifacts are not world-wide readable.
407c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        //  - files are owned by the system uid.
408c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetPrimaryDexArtifact(oat_dir, apk_path_, "odex");
409c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
410c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
411c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
4125bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
4135bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
414c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(odex, kSystemUid, uid, mode);
415c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CheckFileAccess(vdex, kSystemUid, uid, mode);
416c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
4175bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        if (compiler_filter == "speed-profile") {
4185bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle            CheckFileAccess(art, kSystemUid, uid, mode);
4195bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle        }
420c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
421c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
422c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    std::string GetPrimaryDexArtifact(const char* oat_dir,
423c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& dex_path,
424c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                                      const std::string& type) {
425c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        if (oat_dir == nullptr) {
426c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string path = dex_path;
427c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            for (auto it = path.begin() + 1; it < path.end(); ++it) {
428c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                if (*it == '/') {
429c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    *it = '@';
430c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                }
431c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            }
432c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return android_data_dir + DALVIK_CACHE + '/' + kRuntimeIsa + "/" + path
433c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    + "@classes.dex";
434c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        } else {
435c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_end = dex_path.rfind('.');
436c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            std::string::size_type name_start = dex_path.rfind('/');
437c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle            return std::string(oat_dir) + "/" + kRuntimeIsa + "/" +
438c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                    dex_path.substr(name_start + 1, name_end - name_start) + type;
439c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        }
440c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
4417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
4427d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4437d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4447d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCe) {
4457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCe";
44629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
4477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4497d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4507d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCeLink) {
4517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCeLink";
45229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
4537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4547d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4567d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDe) {
4577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDe";
45829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
4597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
4607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4627d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
4637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDoesNotExist";
4647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // If the file validates but does not exist we do not treat it as an error.
46529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
4667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true,  /*compile_ok*/ false);
4677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4697d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
4707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryStorageValidationError";
47129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
4727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
4737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4757d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
4767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
47729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
4787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
4797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4817d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
4827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
48329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
4847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false, kSystemUid);
4857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
487c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryPublic) {
488c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryPublic";
489c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
490c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
491c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
492c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
493c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
494c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
495c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
4965bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin JuravleTEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
4975bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
4985bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    CompilePrimaryDexFail("awesome-filter",
4995bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
5005bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          app_oat_dir_.c_str(),
5015bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          kTestAppGid,
5025bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                          DEX2OAT_FROM_SCRATCH);
5035bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle}
5045bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle
505c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
506c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfileNonPublic";
507c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
5085bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED,
509c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
510c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
511c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
512c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
513c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
514c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
515c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryProfilePublic";
5165bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle    CompilePrimaryDexOk("speed-profile",
5175bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC,
518c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
519c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
520c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
521c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
522c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
523c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
524c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryBackgroundOk";
525c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("speed-profile",
5265bd1c7251a6a3a4318d24c1f89edebfecb98836dCalin Juravle                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED,
527c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
528c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
529c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FROM_SCRATCH);
530c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
531c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
532c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravleclass PrimaryDexReCompilationTest : public DexoptTest {
533c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  public:
534c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void SetUp() {
535c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::SetUp();
536c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        CompilePrimaryDexOk("verify",
537c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
538c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            app_oat_dir_.c_str(),
539c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            kTestAppGid,
540c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                            DEX2OAT_FROM_SCRATCH);
541c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string odex = GetSecondaryDexArtifact(apk_path_, "odex");
542c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        std::string vdex = GetSecondaryDexArtifact(apk_path_, "vdex");
543c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
544c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(open(odex.c_str(), O_RDONLY));
545c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(open(vdex.c_str(), O_RDONLY));
546c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
547c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
548c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    virtual void TearDown() {
549c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_odex_fd_.reset(-1);
550c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        first_compilation_vdex_fd_.reset(-1);
551c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle        DexoptTest::TearDown();
552c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    }
553c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
554c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle  protected:
555c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_odex_fd_;
556c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    unique_fd first_compilation_vdex_fd_;
557c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle};
558c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
559c4f6a0b6333980a069900e2afff2c755f30fe09cCalin JuravleTEST_F(PrimaryDexReCompilationTest, DexoptPrimaryUpdateInPlaceVdex) {
560c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    LOG(INFO) << "DexoptPrimaryUpdateInPlaceVdex";
561c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle
562c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle    CompilePrimaryDexOk("verify",
563c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
564c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        app_oat_dir_.c_str(),
565c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        kTestAppGid,
566c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle                        DEX2OAT_FOR_BOOT_IMAGE);
567c4f6a0b6333980a069900e2afff2c755f30fe09cCalin Juravle}
5687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleclass ReconcileTest : public DexoptTest {
5707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
5717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        DexoptTest::SetUp();
57229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
5737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
57429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
5757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
5767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
5777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
5787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5797d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
5807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeExists";
5817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
5827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5857d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
5867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeLinkExists";
5877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
5887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5917d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
5927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeExists";
5937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
5947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
5957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
5967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
5977d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
5987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
5997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    run_cmd("rm -rf " + secondary_dex_de_);
6007d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
6017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
6027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6047d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
6057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Validation errors will not clean the odex/vdex/art files but will mark
6067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // the file as non existent so that the PM knows it should purge it from its
6077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // records.
6087d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryStorageValidationError";
6097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
6107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
6117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6137d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
6147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
6157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Attempt to reconcile the dex files of the test app from a different app.
6167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string another_app = "another.app";
6177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
6197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
6217d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
6227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
6237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
6247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
6257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
6267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
62729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleclass ProfileTest : public DexoptTest {
62829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle  protected:
62929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string cur_profile_;
63029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string ref_profile_;
63129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string snap_profile_;
63229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
633824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    static constexpr const char* kPrimaryProfile = "primary.prof";
634824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
63529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    virtual void SetUp() {
63629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        DexoptTest::SetUp();
63729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        cur_profile_ = create_current_profile_path(
638824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
639824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
640824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                /*is_secondary_dex*/ false);
641824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
64229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
64329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
644824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
645824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            int32_t num_dex) {
646824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
647824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
648824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile=" + path);
64929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chmod(path.c_str(), mode);
65029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chown(path.c_str(), uid, gid);
65129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
65229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
65329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void SetupProfiles(bool setup_ref) {
65429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
65529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (setup_ref) {
656824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
65729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
65829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
65929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
660c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    void createProfileSnapshot(int32_t appid, const std::string& package_name,
661c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle            bool expected_result) {
66229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result;
663c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
6640d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                appid, package_name, kPrimaryProfile, apk_path_, &result);
66529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(binder_result.isOk());
66629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(expected_result, result);
66729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
66829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!expected_result) {
66929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // Do not check the files if we expect to fail.
67029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return;
67129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
67229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
67329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
67429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
67529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
67629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
67729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string expected_profile_content = snap_profile_ + ".expected";
67829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("rm -f " + expected_profile_content);
67929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("touch " + expected_profile_content);
68029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
68129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --profile-file=" + ref_profile_ +
68240b5f46cafa02d48d58b3d5a458df5aceaba52e9Calin Juravle                " --reference-profile-file=" + expected_profile_content +
68340b5f46cafa02d48d58b3d5a458df5aceaba52e9Calin Juravle                " --apk=" + apk_path_);
68429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
68529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
68629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
68729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        pid_t pid = fork();
68829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (pid == 0) {
68929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            /* child */
69029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            TransitionToSystemServer();
69129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
69229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // System server should be able to open the the spanshot.
69329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
69429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
69529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            _exit(0);
69629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
69729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        /* parent */
69829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
69929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
70029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
701408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    void mergePackageProfiles(const std::string& package_name,
702408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              const std::string& code_path,
703408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              bool expected_result) {
704824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        bool result;
705824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        binder::Status binder_result = service_->mergeProfiles(
706408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                kTestAppUid, package_name, code_path, &result);
707824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(binder_result.isOk());
708824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_EQ(expected_result, result);
709824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
710824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        if (!expected_result) {
711824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            // Do not check the files if we expect to fail.
712824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            return;
713824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        }
714824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
715824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
716824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
717824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
718824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
719824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        std::string ref_profile_content = ref_profile_ + ".expected";
720824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("rm -f " + ref_profile_content);
721824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("touch " + ref_profile_content);
722824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
723824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --profile-file=" + ref_profile_ +
724824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --reference-profile-file=" + ref_profile_content);
725824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
726824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
727824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    }
728824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
729c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // TODO(calin): add dex metadata tests once the ART change is merged.
730c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
731c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            bool expected_result) {
732c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        bool result;
733c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        binder::Status binder_result = service_->prepareAppProfile(
734c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                package_name, kTestUserId, kTestAppId, profile_name, /*code path*/ "base.apk",
735c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                /*dex_metadata*/ nullptr, &result);
736c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_TRUE(binder_result.isOk());
737c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(expected_result, result);
738c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
739c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        if (!expected_result) {
740c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            // Do not check the files if we expect to fail.
741c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            return;
742c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        }
743c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
744c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_cur_prof = create_current_profile_path(
745c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
746c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_ref_profile = create_reference_profile_path(package_name,
747c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                profile_name, /*is_secondary_dex*/ false);
748c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
749c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Check that we created the current profile.
750c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
751c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
752c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Without dex metadata we don't generate a reference profile.
753c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
754c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    }
755c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
7560d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
75729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void TransitionToSystemServer() {
75829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
75929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        int32_t res = selinux_android_setcontext(
76029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                kSystemUid, true, se_info_.c_str(), "system_server");
76129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
76229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
76329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
76429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool AreFilesEqual(const std::string& file1, const std::string& file2) {
76529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content1;
76629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content2;
76729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
76829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file1, &content1)) return false;
76929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file2, &content2)) return false;
77029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return content1 == content2;
77129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
77229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
77329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
77429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        unique_fd fd(open(file.c_str(), O_RDONLY));
77529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fd < 0) {
77629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to open " << file;
77729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
77829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
77929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
78029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fstat(fd, &st) != 0) {
78129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to stat " << file;
78229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
78329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
78429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        content->resize(st.st_size);
78529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result = ReadFully(fd, content->data(), content->size());
78629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!result) {
78729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to read " << file;
78829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
78929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return result;
79029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
79129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle};
79229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
79329591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOk) {
79429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOk";
79529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
79629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
797c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
79829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
79929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// The reference profile is created on the fly. We need to be able to
80129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// snapshot without one.
80229591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
80329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOkNoReference";
80429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ false);
806c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
80729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
80829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
80929591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
81029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotFailWrongPackage";
81129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
81229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
813c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
81429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
81529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
81629591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
81729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotDestroySnapshot";
81829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
81929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
820c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
82129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
822824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    binder::Status binder_result = service_->destroyProfileSnapshot(package_name_, kPrimaryProfile);
82329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_TRUE(binder_result.isOk());
82429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    struct stat st;
82529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
82629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(ENOENT, errno);
82729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
82829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
829824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOk) {
830824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOk";
831824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
832824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
833408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
834824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
835824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
836824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// The reference profile is created on the fly. We need to be able to
837824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// merge without one.
838824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOkNoReference) {
839824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOkNoReference";
840824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
841824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ false);
842408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
843824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
844824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
845824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
846824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeFailWrongPackage";
847824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
848824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
849408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
850824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
851824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
852d2affb8601630fe682b03407fc907f2439ff5370Calin JuravleTEST_F(ProfileTest, ProfileDirOk) {
853d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    LOG(INFO) << "ProfileDirOk";
854d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
855d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
856d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            kTestUserId, package_name_);
857d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
858824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
859d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
860d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
861d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
8626f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
8636f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle}
8646f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8656f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// Verify that the profile directories are fixed up during an upgrade.
8666f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// (The reference profile directory is prepared lazily).
8676f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin JuravleTEST_F(ProfileTest, ProfileDirOkAfterFixup) {
8686f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    LOG(INFO) << "ProfileDirOkAfterFixup";
8696f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8706f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
8716f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId, package_name_);
8726f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
873824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
8746f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
8756f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8766f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
8776f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
8786f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
8796f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8806f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Run createAppData again which will offer to fix-up the profile directories.
8816f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_TRUE(service_->createAppData(
8826f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            volume_uuid_,
8836f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            package_name_,
8846f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId,
8856f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kAppDataFlags,
8866f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestAppUid,
8876f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            se_info_,
8886f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kOSdkVersion,
8896f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            &ce_data_inode_).isOk());
8906f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
8916f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Check the file access.
8926f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
8936f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
894d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle}
895d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
896c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareOk) {
897c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareOk";
898c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
899c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
900c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
901c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
902c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailInvalidPackage";
903c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
904c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
905c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
906c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
907c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
908c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    SetupProfiles(/*setup_ref*/ false);
909c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // Change the uid on the profile to trigger a failure.
910c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
911c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
912c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
913c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
9140d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9150d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravleclass BootProfileTest : public ProfileTest {
9160d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  public:
9170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void setup() {
9180d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::SetUp();
9190d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        intial_android_profiles_dir = android_profiles_dir;
9200d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9210d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9220d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void TearDown() {
9230d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = intial_android_profiles_dir;
9240d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::TearDown();
9250d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9260d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9270d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void UpdateAndroidProfilesDir(const std::string& profile_dir) {
9280d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = profile_dir;
9290d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // We need to create the reference profile directory in the new profile dir.
9300d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        run_cmd("mkdir -p " + profile_dir + "/ref");
9310d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9320d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9330d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
9340d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        bool result;
9350d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
9360d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                -1, "android", "android.prof", classpath, &result);
9370d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(binder_result.isOk());
9380d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_EQ(expected_result, result);
9390d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9400d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (!expected_result) {
9410d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // Do not check the files if we expect to fail.
9420d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            return;
9430d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
9440d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9450d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // Check that the snapshot was created with he expected access flags.
9460d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
9470d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
9480d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9490d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        pid_t pid = fork();
9500d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (pid == 0) {
9510d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            /* child */
9520d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            TransitionToSystemServer();
9530d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9540d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // System server should be able to open the snapshot.
9550d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
9560d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
9570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            _exit(0);
9580d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
9590d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        /* parent */
9600d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
9610d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
9620d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
9630d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string intial_android_profiles_dir;
9640d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle};
9650d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9660d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOk) {
9670d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOk";
9680d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
9690d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
9700d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
9710d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9720d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9730d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
9740d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
9750d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9760d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
9770d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9780d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9790d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
9800d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
9810d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
9820d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
9830d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9840d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
9850d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Still, this is not a failure case.
9860d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_apk_dir_);
9870d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
9880d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
9890d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9900d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle// Verify that profile collection.
9910d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, CollectProfiles) {
9920d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "CollectProfiles";
9930d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
9940d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some profile directories mimicking the real profile structure.
9950d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
9960d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
9970d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
9980d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create an empty profile.
9990d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
10000d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create a random file.
10010d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
10020d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10030d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some non-empty profiles.
10040d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
10050d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + current_prof);
10060d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
10070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + ref_prof);
10080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10090d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
10100d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10110d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::vector<std::string> profiles;
10120d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    collect_profiles(&profiles);
10130d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10140d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Only two profiles should be in the output.
10150d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_EQ(2u, profiles.size());
10160d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
10170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
10180d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
10190d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
10207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace installd
10217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace android
1022