installd_dexopt_test.cpp revision 0d0a49205ff08bdf23124455b6b31ace81edd4f6
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_;
1627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1637d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    int64_t ce_data_inode_;
1647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_ce_;
1667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_ce_link_;
1677d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string secondary_dex_de_;
1687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1697d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
1707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        setenv("ANDROID_LOG_TAGS", "*:v", 1);
1717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        android::base::InitLogging(nullptr);
17229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Initialize the globals holding the file system main paths (/data/, /system/ etc..).
17329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // This is needed in order to compute the application and profile paths.
17429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(init_globals_from_data_and_root());
17529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Initialize selinux log callbacks.
17629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // This ensures that selinux is up and running and re-directs the selinux messages
17729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // to logcat (in order to make it easier to investigate test results).
17829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(init_selinux());
1797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        service_ = new InstalldNativeService();
1807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        volume_uuid_ = nullptr;
1827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        package_name_ = "com.installd.test.dexopt";
1837d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        se_info_ = "default";
1847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_apk_dir_ = android_app_dir + package_name_;
1857d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        create_mock_app();
1877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
1887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
1897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void TearDown() {
1907d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        if (!kDebug) {
1917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            service_->destroyAppData(
1927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_, package_name_, kTestUserId, kAppDataFlags, ce_data_inode_);
1937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_apk_dir_);
1947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_private_dir_ce_);
1957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            run_cmd("rm -rf " + app_private_dir_de_);
1967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        }
1977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        delete service_;
1987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
1997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2007d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void create_mock_app() {
2017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create the oat dir.
2027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string app_oat_dir = app_apk_dir_ + "/oat";
2037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755);
2047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        service_->createOatDir(app_oat_dir, kRuntimeIsa);
2057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Copy the primary apk.
2070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        apk_path_ = app_apk_dir_ + "/base.jar";
2080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, apk_path_, kSystemUid, kSystemGid, 0644));
2097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create the app user data.
2117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(service_->createAppData(
2127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
2137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_name_,
2147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kTestUserId,
2157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kAppDataFlags,
2167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kTestAppUid,
2177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            se_info_,
2187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            kOSdkVersion,
2197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &ce_data_inode_).isOk());
2207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create a secondary dex file on CE storage
2227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        const char* volume_uuid_cstr = volume_uuid_ == nullptr ? nullptr : volume_uuid_->c_str();
2237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_private_dir_ce_ = create_data_user_ce_package_path(
2247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_ce_ = app_private_dir_ce_ + "/secondary_ce.jar";
2267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, secondary_dex_ce_, kTestAppUid, kTestAppGid, 0600));
2277d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string app_private_dir_ce_link = create_data_user_ce_package_path_as_user_link(
2287d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_ce_link_ = app_private_dir_ce_link + "/secondary_ce.jar";
2307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Create a secondary dex file on DE storage.
2327d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        app_private_dir_de_ = create_data_user_de_package_path(
2337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                volume_uuid_cstr, kTestUserId, package_name_.c_str());
2347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        secondary_dex_de_ = app_private_dir_de_ + "/secondary_de.jar";
2357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(WriteBase64ToFile(kDexFile, secondary_dex_de_, kTestAppUid, kTestAppGid, 0600));
2367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        // Fix app data uid.
2387d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_TRUE(service_->fixupAppData(volume_uuid_, kTestUserId).isOk());
2397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
24229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string GetSecondaryDexArtifact(const std::string& path, const std::string& type) {
2437d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string::size_type end = path.rfind('.');
2447d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string::size_type start = path.rfind('/', end);
2457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        return path.substr(0, start) + "/oat/" + kRuntimeIsa + "/" +
2467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                path.substr(start + 1, end - start) + type;
2477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2487d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
24929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
2507d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_be_compiled = true,
251d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            int32_t uid = -1) {
252d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
253d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
254d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
2557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
2567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int32_t dexopt_needed = 0;  // does not matter;
2577d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> out_path = nullptr;  // does not matter
2587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
2597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::string compiler_filter = "speed-profile";
2607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
2617d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
2627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool downgrade = false;
263570d398770a12613461408b767ae97b549393157David Brazdil        int32_t target_sdk_version = 0;  // default
264408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle        std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
265408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle
266408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle        bool prof_result;
267408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle        binder::Status prof_binder_result = service_->prepareAppProfile(
268408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                package_name_, kTestUserId, kTestAppId, *profile_name_ptr, /*code path*/ "base.apk",
269408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                /*dex_metadata*/ nullptr, &prof_result);
270408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle        ASSERT_TRUE(prof_binder_result.isOk());
271408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle        ASSERT_TRUE(prof_result);
2727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->dexopt(path,
2737d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 uid,
2747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 package_name_ptr,
2757d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 kRuntimeIsa,
2767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dexopt_needed,
2777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 out_path,
2787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 dex_flags,
2797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 compiler_filter,
2807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 volume_uuid_,
2817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 class_loader_context_ptr,
2827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle                                                 se_info_ptr,
283570d398770a12613461408b767ae97b549393157David Brazdil                                                 downgrade,
284408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 target_sdk_version,
285408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                                                 profile_name_ptr);
2867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
2877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_compiled ? 0 : -1;
28829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
28929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
29029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
2917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
2927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
2937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
2947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
2957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
2967d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
2977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
298d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            int32_t uid = -1, std::string* package_override = nullptr) {
299d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        if (uid == -1) {
300d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            uid = kTestAppUid;
301d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle        }
3027d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        std::vector<std::string> isas;
3037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        isas.push_back(kRuntimeIsa);
3047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        bool out_secondary_dex_exists = false;
3057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        binder::Status result = service_->reconcileSecondaryDexFile(
3067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            path,
3077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            package_override == nullptr ? package_name_ : *package_override,
3087d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            uid,
3097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            isas,
3107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            volume_uuid_,
3117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            storage_flag,
3127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            &out_secondary_dex_exists);
3137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_binder_call_succeed, result.isOk());
3157d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
3167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        int expected_access = should_dex_be_deleted ? -1 : 0;
31829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string odex = GetSecondaryDexArtifact(path, "odex");
31929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string vdex = GetSecondaryDexArtifact(path, "vdex");
32029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string art = GetSecondaryDexArtifact(path, "art");
3217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
3227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
3237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
3247d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
32529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
32629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
32729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
32829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, stat(file.c_str(), &st));
32929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(uid, st.st_uid);
33029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(gid, st.st_gid);
33129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(mode, st.st_mode);
33229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
3337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
3347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3367d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCe) {
3377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCe";
33829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
3397d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
3407d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3417d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3427d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryCeLink) {
3437d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryCeLink";
34429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
3457d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
3467d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3477d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3487d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDe) {
3497d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDe";
35029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
3517d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*compile_ok*/ true);
3527d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3537d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3547d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
3557d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryDoesNotExist";
3567d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // If the file validates but does not exist we do not treat it as an error.
35729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
3587d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true,  /*compile_ok*/ false);
3597d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3607d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3617d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
3627d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryStorageValidationError";
36329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
3647d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
3657d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3667d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3677d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
3687d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
36929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
3707d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false);
3717d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3727d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3737d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
3747d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
37529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
3767d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ false,  /*compile_ok*/ false, kSystemUid);
3777d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3787d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3797d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3807d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravleclass ReconcileTest : public DexoptTest {
3817d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    virtual void SetUp() {
3827d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        DexoptTest::SetUp();
38329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
3847d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
38529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
3867d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle            /*binder_ok*/ true, /*compile_ok*/ true);
3877d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    }
3887d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle};
3897d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3907d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
3917d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeExists";
3927d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
3937d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
3947d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
3957d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
3967d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
3977d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryCeLinkExists";
3987d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
3997d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
4007d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4017d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4027d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
4037d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeExists";
4047d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
4057d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
4067d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4077d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4087d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
4097d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
4107d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    run_cmd("rm -rf " + secondary_dex_de_);
4117d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
4127d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
4137d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4147d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4157d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
4167d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Validation errors will not clean the odex/vdex/art files but will mark
4177d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // the file as non existent so that the PM knows it should purge it from its
4187d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // records.
4197d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryStorageValidationError";
4207d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
4217d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
4227d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4237d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4247d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
4257d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
4267d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    // Attempt to reconcile the dex files of the test app from a different app.
4277d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    std::string another_app = "another.app";
4287d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
4297d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
4307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
4327d7654646abb84bbae6b245de270ac087cdc8a95Calin JuravleTEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
4337d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
4347d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle    reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
4357d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle        /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
4367d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}
4377d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle
43829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravleclass ProfileTest : public DexoptTest {
43929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle  protected:
44029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string cur_profile_;
44129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string ref_profile_;
44229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    std::string snap_profile_;
44329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
444824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    static constexpr const char* kPrimaryProfile = "primary.prof";
445824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
44629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    virtual void SetUp() {
44729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        DexoptTest::SetUp();
44829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        cur_profile_ = create_current_profile_path(
449824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
450824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
451824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                /*is_secondary_dex*/ false);
452824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
45329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
45429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
455824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
456824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            int32_t num_dex) {
457824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
458824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
459824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --generate-test-profile=" + path);
46029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chmod(path.c_str(), mode);
46129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ::chown(path.c_str(), uid, gid);
46229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
46329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
46429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void SetupProfiles(bool setup_ref) {
46529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
46629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (setup_ref) {
467824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
46829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
46929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
47029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
471c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    void createProfileSnapshot(int32_t appid, const std::string& package_name,
472c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle            bool expected_result) {
47329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result;
474c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
4750d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                appid, package_name, kPrimaryProfile, apk_path_, &result);
47629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(binder_result.isOk());
47729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(expected_result, result);
47829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
47929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!expected_result) {
48029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // Do not check the files if we expect to fail.
48129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return;
48229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
48329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
48429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
48529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
48629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
48729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
48829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::string expected_profile_content = snap_profile_ + ".expected";
48929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("rm -f " + expected_profile_content);
49029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("touch " + expected_profile_content);
49129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
49229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --profile-file=" + ref_profile_ +
49329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                " --reference-profile-file=" + expected_profile_content);
49429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
49529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
49629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
49729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        pid_t pid = fork();
49829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (pid == 0) {
49929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            /* child */
50029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            TransitionToSystemServer();
50129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
50229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            // System server should be able to open the the spanshot.
50329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
50429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
50529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            _exit(0);
50629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
50729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        /* parent */
50829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
50929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
51029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
511408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    void mergePackageProfiles(const std::string& package_name,
512408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              const std::string& code_path,
513408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                              bool expected_result) {
514824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        bool result;
515824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        binder::Status binder_result = service_->mergeProfiles(
516408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle                kTestAppUid, package_name, code_path, &result);
517824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(binder_result.isOk());
518824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_EQ(expected_result, result);
519824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
520824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        if (!expected_result) {
521824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            // Do not check the files if we expect to fail.
522824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            return;
523824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        }
524824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
525824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // Check that the snapshot was created witht he expected acess flags.
526824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
527824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
528824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        // The snapshot should be equivalent to the merge of profiles.
529824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        std::string ref_profile_content = ref_profile_ + ".expected";
530824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("rm -f " + ref_profile_content);
531824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("touch " + ref_profile_content);
532824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        run_cmd("profman --profile-file=" + cur_profile_ +
533824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --profile-file=" + ref_profile_ +
534824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle                " --reference-profile-file=" + ref_profile_content);
535824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
536824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle        ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
537824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    }
538824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
539c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // TODO(calin): add dex metadata tests once the ART change is merged.
540c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
541c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            bool expected_result) {
542c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        bool result;
543c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        binder::Status binder_result = service_->prepareAppProfile(
544c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                package_name, kTestUserId, kTestAppId, profile_name, /*code path*/ "base.apk",
545c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                /*dex_metadata*/ nullptr, &result);
546c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_TRUE(binder_result.isOk());
547c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(expected_result, result);
548c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
549c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        if (!expected_result) {
550c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            // Do not check the files if we expect to fail.
551c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle            return;
552c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        }
553c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
554c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_cur_prof = create_current_profile_path(
555c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
556c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        std::string code_path_ref_profile = create_reference_profile_path(package_name,
557c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle                profile_name, /*is_secondary_dex*/ false);
558c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
559c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Check that we created the current profile.
560c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
561c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
562c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        // Without dex metadata we don't generate a reference profile.
563c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle        ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
564c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    }
565c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
5660d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
56729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    void TransitionToSystemServer() {
56829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
56929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        int32_t res = selinux_android_setcontext(
57029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle                kSystemUid, true, se_info_.c_str(), "system_server");
57129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
57229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
57329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
57429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool AreFilesEqual(const std::string& file1, const std::string& file2) {
57529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content1;
57629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        std::vector<uint8_t> content2;
57729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
57829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file1, &content1)) return false;
57929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!ReadAll(file2, &content2)) return false;
58029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return content1 == content2;
58129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
58229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
58329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
58429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        unique_fd fd(open(file.c_str(), O_RDONLY));
58529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fd < 0) {
58629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to open " << file;
58729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
58829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
58929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        struct stat st;
59029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (fstat(fd, &st) != 0) {
59129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to stat " << file;
59229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            return false;
59329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
59429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        content->resize(st.st_size);
59529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        bool result = ReadFully(fd, content->data(), content->size());
59629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        if (!result) {
59729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle            PLOG(ERROR) << "Failed to read " << file;
59829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        }
59929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle        return result;
60029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    }
60129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle};
60229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
60329591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOk) {
60429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOk";
60529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
60629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
607c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
60829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
60929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
61029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// The reference profile is created on the fly. We need to be able to
61129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle// snapshot without one.
61229591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
61329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotOkNoReference";
61429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
61529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ false);
616c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
61729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
61829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
61929591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
62029591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotFailWrongPackage";
62129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
62229591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
623c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
62429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
62529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
62629591736958a7ed45f4b5982ca9a46756baa0f6dCalin JuravleTEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
62729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    LOG(INFO) << "ProfileSnapshotDestroySnapshot";
62829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
62929591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    SetupProfiles(/*setup_ref*/ true);
630c3596c32071920e020f016e6fc38b69ba4f1b38aCalin Juravle    createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
63129591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
632824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    binder::Status binder_result = service_->destroyProfileSnapshot(package_name_, kPrimaryProfile);
63329591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_TRUE(binder_result.isOk());
63429591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    struct stat st;
63529591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
63629591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle    ASSERT_EQ(ENOENT, errno);
63729591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle}
63829591736958a7ed45f4b5982ca9a46756baa0f6dCalin Juravle
639824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOk) {
640824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOk";
641824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
642824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
643408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
644824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
645824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
646824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// The reference profile is created on the fly. We need to be able to
647824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle// merge without one.
648824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeOkNoReference) {
649824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeOkNoReference";
650824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
651824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ false);
652408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
653824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
654824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
655824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin JuravleTEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
656824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    LOG(INFO) << "ProfileMergeFailWrongPackage";
657824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
658824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle    SetupProfiles(/*setup_ref*/ true);
659408cd4ab394ce6640f43665639bc3fb0ac296ca6Calin Juravle    mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
660824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle}
661824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle
662d2affb8601630fe682b03407fc907f2439ff5370Calin JuravleTEST_F(ProfileTest, ProfileDirOk) {
663d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    LOG(INFO) << "ProfileDirOk";
664d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
665d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
666d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle            kTestUserId, package_name_);
667d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
668824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
669d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
670d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
671d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
6726f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
6736f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle}
6746f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
6756f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// Verify that the profile directories are fixed up during an upgrade.
6766f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle// (The reference profile directory is prepared lazily).
6776f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin JuravleTEST_F(ProfileTest, ProfileDirOkAfterFixup) {
6786f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    LOG(INFO) << "ProfileDirOkAfterFixup";
6796f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
6806f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
6816f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId, package_name_);
6826f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
683824a64db8db2e9bf5c601f2568544ea1c3b4dd3eCalin Juravle            kPrimaryProfile, /*is_secondary_dex*/false);
6846f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
6856f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
6866f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
6876f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
6886f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
6896f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
6906f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Run createAppData again which will offer to fix-up the profile directories.
6916f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    ASSERT_TRUE(service_->createAppData(
6926f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            volume_uuid_,
6936f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            package_name_,
6946f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestUserId,
6956f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kAppDataFlags,
6966f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kTestAppUid,
6976f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            se_info_,
6986f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            kOSdkVersion,
6996f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle            &ce_data_inode_).isOk());
7006f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle
7016f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    // Check the file access.
7026f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
7036f06eb679ae105a9d1bb8910dbd1f734bd62435bCalin Juravle    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
704d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle}
705d2affb8601630fe682b03407fc907f2439ff5370Calin Juravle
706c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareOk) {
707c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareOk";
708c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
709c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
710c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
711c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
712c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailInvalidPackage";
713c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
714c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
715c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
716c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin JuravleTEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
717c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
718c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    SetupProfiles(/*setup_ref*/ false);
719c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    // Change the uid on the profile to trigger a failure.
720c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
721c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle    preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
722c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle}
723c3b049e0294a5884b18f0f29f3af14e6de0803c7Calin Juravle
7240d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7250d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravleclass BootProfileTest : public ProfileTest {
7260d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  public:
7270d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void setup() {
7280d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::SetUp();
7290d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        intial_android_profiles_dir = android_profiles_dir;
7300d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
7310d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7320d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    virtual void TearDown() {
7330d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = intial_android_profiles_dir;
7340d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ProfileTest::TearDown();
7350d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
7360d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7370d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void UpdateAndroidProfilesDir(const std::string& profile_dir) {
7380d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        android_profiles_dir = profile_dir;
7390d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // We need to create the reference profile directory in the new profile dir.
7400d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        run_cmd("mkdir -p " + profile_dir + "/ref");
7410d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
7420d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7430d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
7440d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        bool result;
7450d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        binder::Status binder_result = service_->createProfileSnapshot(
7460d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle                -1, "android", "android.prof", classpath, &result);
7470d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(binder_result.isOk());
7480d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_EQ(expected_result, result);
7490d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7500d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (!expected_result) {
7510d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // Do not check the files if we expect to fail.
7520d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            return;
7530d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
7540d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7550d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        // Check that the snapshot was created with he expected access flags.
7560d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
7570d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
7580d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7590d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        pid_t pid = fork();
7600d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        if (pid == 0) {
7610d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            /* child */
7620d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            TransitionToSystemServer();
7630d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7640d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            // System server should be able to open the snapshot.
7650d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
7660d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
7670d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle            _exit(0);
7680d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        }
7690d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        /* parent */
7700d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle        ASSERT_TRUE(WIFEXITED(wait_child(pid)));
7710d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    }
7720d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle  protected:
7730d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string intial_android_profiles_dir;
7740d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle};
7750d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7760d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOk) {
7770d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOk";
7780d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
7790d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
7800d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
7810d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
7820d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7830d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
7840d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
7850d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7860d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
7870d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
7880d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7890d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
7900d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
7910d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    char* boot_classpath = getenv("BOOTCLASSPATH");
7920d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(boot_classpath != nullptr);
7930d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
7940d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
7950d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Still, this is not a failure case.
7960d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_apk_dir_);
7970d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
7980d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
7990d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8000d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle// Verify that profile collection.
8010d0a49205ff08bdf23124455b6b31ace81edd4f6Calin JuravleTEST_F(BootProfileTest, CollectProfiles) {
8020d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    LOG(INFO) << "CollectProfiles";
8030d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8040d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some profile directories mimicking the real profile structure.
8050d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
8060d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
8070d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
8080d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create an empty profile.
8090d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
8100d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create a random file.
8110d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
8120d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8130d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Create some non-empty profiles.
8140d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
8150d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + current_prof);
8160d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
8170d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    run_cmd("echo 1 > " + ref_prof);
8180d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8190d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
8200d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8210d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    std::vector<std::string> profiles;
8220d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    collect_profiles(&profiles);
8230d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8240d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    // Only two profiles should be in the output.
8250d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_EQ(2u, profiles.size());
8260d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
8270d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle    ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
8280d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle}
8290d0a49205ff08bdf23124455b6b31ace81edd4f6Calin Juravle
8307d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace installd
8317d7654646abb84bbae6b245de270ac087cdc8a95Calin Juravle}  // namespace android
832