Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <cstdlib>
     18 #include <fcntl.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 #include <sys/types.h>
     22 #include <sys/stat.h>
     23 
     24 #include <android-base/file.h>
     25 #include <android-base/logging.h>
     26 #include <android-base/properties.h>
     27 #include <android-base/scopeguard.h>
     28 #include <android-base/stringprintf.h>
     29 #include <android-base/unique_fd.h>
     30 #include <binder/Status.h>
     31 #include <cutils/properties.h>
     32 
     33 #include <gtest/gtest.h>
     34 
     35 #include <selinux/android.h>
     36 #include <selinux/avc.h>
     37 
     38 #include "binder_test_utils.h"
     39 #include "dexopt.h"
     40 #include "InstalldNativeService.h"
     41 #include "globals.h"
     42 #include "tests/test_utils.h"
     43 #include "utils.h"
     44 
     45 using android::base::ReadFully;
     46 using android::base::unique_fd;
     47 
     48 namespace android {
     49 namespace installd {
     50 
     51 // TODO(calin): try to dedup this code.
     52 #if defined(__arm__)
     53 static const std::string kRuntimeIsa = "arm";
     54 #elif defined(__aarch64__)
     55 static const std::string kRuntimeIsa = "arm64";
     56 #elif defined(__mips__) && !defined(__LP64__)
     57 static const std::string kRuntimeIsa = "mips";
     58 #elif defined(__mips__) && defined(__LP64__)
     59 static const std::string kRuntimeIsa = "mips64";
     60 #elif defined(__i386__)
     61 static const std::string kRuntimeIsa = "x86";
     62 #elif defined(__x86_64__)
     63 static const std::string kRuntimeIsa = "x86_64";
     64 #else
     65 static const std::string kRuntimeIsa = "none";
     66 #endif
     67 
     68 int get_property(const char *key, char *value, const char *default_value) {
     69     return property_get(key, value, default_value);
     70 }
     71 
     72 bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
     73         const char *instruction_set) {
     74     return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
     75 }
     76 
     77 bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
     78         const char *instruction_set) {
     79     return calculate_odex_file_path_default(path, apk_path, instruction_set);
     80 }
     81 
     82 bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
     83     return create_cache_path_default(path, src, instruction_set);
     84 }
     85 
     86 static void run_cmd(const std::string& cmd) {
     87     system(cmd.c_str());
     88 }
     89 
     90 template <typename Visitor>
     91 static void run_cmd_and_process_output(const std::string& cmd, const Visitor& visitor) {
     92     FILE* file = popen(cmd.c_str(), "r");
     93     CHECK(file != nullptr) << "Failed to ptrace " << cmd;
     94     char* line = nullptr;
     95     while (true) {
     96         size_t n = 0u;
     97         ssize_t value = getline(&line, &n, file);
     98         if (value == -1) {
     99             break;
    100         }
    101         visitor(line);
    102     }
    103     free(line);
    104     fclose(file);
    105 }
    106 
    107 static int mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
    108     int ret = ::mkdir(path.c_str(), mode);
    109     if (ret != 0) {
    110         return ret;
    111     }
    112     ret = ::chown(path.c_str(), owner, group);
    113     if (ret != 0) {
    114         return ret;
    115     }
    116     return ::chmod(path.c_str(), mode);
    117 }
    118 
    119 static int log_callback(int type, const char *fmt, ...) { // NOLINT
    120     va_list ap;
    121     int priority;
    122 
    123     switch (type) {
    124         case SELINUX_WARNING:
    125             priority = ANDROID_LOG_WARN;
    126             break;
    127         case SELINUX_INFO:
    128             priority = ANDROID_LOG_INFO;
    129             break;
    130         default:
    131             priority = ANDROID_LOG_ERROR;
    132             break;
    133     }
    134     va_start(ap, fmt);
    135     LOG_PRI_VA(priority, "SELinux", fmt, ap);
    136     va_end(ap);
    137     return 0;
    138 }
    139 
    140 static bool init_selinux() {
    141     int selinux_enabled = (is_selinux_enabled() > 0);
    142 
    143     union selinux_callback cb;
    144     cb.func_log = log_callback;
    145     selinux_set_callback(SELINUX_CB_LOG, cb);
    146 
    147     if (selinux_enabled && selinux_status_open(true) < 0) {
    148         LOG(ERROR) << "Could not open selinux status; exiting";
    149         return false;
    150     }
    151 
    152     return true;
    153 }
    154 
    155 // Base64 encoding of a simple dex files with 2 methods.
    156 static const char kDexFile[] =
    157     "UEsDBBQAAAAIAOiOYUs9y6BLCgEAABQCAAALABwAY2xhc3Nlcy5kZXhVVAkAA/Ns+lkOHv1ZdXgL"
    158     "AAEEI+UCAASIEwAAS0mt4DIwNmX4qpn7j/2wA7v7N+ZvoQpCJRlVx5SWa4YaiDAxMBQwMDBUhJkI"
    159     "MUBBDyMDAzsDRJwFxAdioBDDHAYEYAbiFUAM1M5wAIhFGCGKDIDYAogdgNgDiH2BOAiI0xghekDm"
    160     "sQIxGxQzM6ACRijNhCbOhCZfyohdPYyuh8szgtVkMkLsLhAAqeCDi+ejibPZZOZlltgxsDnqZSWW"
    161     "JTKwOUFoZh9HayDhZM0g5AMS0M9JzEvX90/KSk0usWZgDAMaws5nAyXBzmpoYGlgAjsAyJoBMp0b"
    162     "zQ8gGhbOTEhhzYwU3qxIYc2GFN6MClC/AhUyKUDMAYU9M1Qc5F8GKBscVgIQM0FxCwBQSwECHgMU"
    163     "AAAACADojmFLPcugSwoBAAAUAgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAA/Ns"
    164     "+ll1eAsAAQQj5QIABIgTAABQSwUGAAAAAAEAAQBRAAAATwEAAAAA";
    165 
    166 class DexoptTestEnvTest : public testing::Test {
    167 };
    168 
    169 TEST_F(DexoptTestEnvTest, CheckSelinux) {
    170     ASSERT_EQ(1, is_selinux_enabled());
    171 
    172     // Crude cutout for virtual devices.
    173 #if !defined(__i386__) && !defined(__x86_64__)
    174     constexpr bool kIsX86 = false;
    175 #else
    176     constexpr bool kIsX86 = true;
    177 #endif
    178     ASSERT_TRUE(1 == security_getenforce() || kIsX86 || true /* b/119032200 */);
    179 }
    180 
    181 class DexoptTest : public testing::Test {
    182 protected:
    183     static constexpr bool kDebug = false;
    184     static constexpr uid_t kSystemUid = 1000;
    185     static constexpr uid_t kSystemGid = 1000;
    186     static constexpr int32_t kOSdkVersion = 25;
    187     static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
    188     static constexpr int32_t kTestUserId = 0;
    189     static constexpr uid_t kTestAppId = 19999;
    190 
    191     const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId);
    192     const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId);
    193 
    194     InstalldNativeService* service_;
    195     std::unique_ptr<std::string> volume_uuid_;
    196     std::string package_name_;
    197     std::string apk_path_;
    198     std::string app_apk_dir_;
    199     std::string app_private_dir_ce_;
    200     std::string app_private_dir_de_;
    201     std::string se_info_;
    202     std::string app_oat_dir_;
    203 
    204     int64_t ce_data_inode_;
    205 
    206     std::string secondary_dex_ce_;
    207     std::string secondary_dex_ce_link_;
    208     std::string secondary_dex_de_;
    209 
    210     virtual void SetUp() {
    211         setenv("ANDROID_LOG_TAGS", "*:v", 1);
    212         android::base::InitLogging(nullptr);
    213         // Initialize the globals holding the file system main paths (/data/, /system/ etc..).
    214         // This is needed in order to compute the application and profile paths.
    215         ASSERT_TRUE(init_globals_from_data_and_root());
    216         // Initialize selinux log callbacks.
    217         // This ensures that selinux is up and running and re-directs the selinux messages
    218         // to logcat (in order to make it easier to investigate test results).
    219         ASSERT_TRUE(init_selinux());
    220         service_ = new InstalldNativeService();
    221 
    222         volume_uuid_ = nullptr;
    223         package_name_ = "com.installd.test.dexopt";
    224         se_info_ = "default";
    225         app_apk_dir_ = android_app_dir + package_name_;
    226 
    227         ASSERT_TRUE(create_mock_app());
    228     }
    229 
    230     virtual void TearDown() {
    231         if (!kDebug) {
    232             service_->destroyAppData(
    233                 volume_uuid_, package_name_, kTestUserId, kAppDataFlags, ce_data_inode_);
    234             run_cmd("rm -rf " + app_apk_dir_);
    235             run_cmd("rm -rf " + app_private_dir_ce_);
    236             run_cmd("rm -rf " + app_private_dir_de_);
    237         }
    238         delete service_;
    239     }
    240 
    241     ::testing::AssertionResult create_mock_app() {
    242         // Create the oat dir.
    243         app_oat_dir_ = app_apk_dir_ + "/oat";
    244         // For debug mode, the directory might already exist. Avoid erroring out.
    245         if (mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755) != 0 && !kDebug) {
    246             return ::testing::AssertionFailure() << "Could not create app dir " << app_apk_dir_
    247                                                  << " : " << strerror(errno);
    248         }
    249         binder::Status status = service_->createOatDir(app_oat_dir_, kRuntimeIsa);
    250         if (!status.isOk()) {
    251             return ::testing::AssertionFailure() << "Could not create oat dir: "
    252                                                  << status.toString8().c_str();
    253         }
    254 
    255         // Copy the primary apk.
    256         apk_path_ = app_apk_dir_ + "/base.jar";
    257         std::string error_msg;
    258         if (!WriteBase64ToFile(kDexFile, apk_path_, kSystemUid, kSystemGid, 0644, &error_msg)) {
    259             return ::testing::AssertionFailure() << "Could not write base64 file to " << apk_path_
    260                                                  << " : " << error_msg;
    261         }
    262 
    263         // Create the app user data.
    264         status = service_->createAppData(
    265                 volume_uuid_,
    266                 package_name_,
    267                 kTestUserId,
    268                 kAppDataFlags,
    269                 kTestAppUid,
    270                 se_info_,
    271                 kOSdkVersion,
    272                 &ce_data_inode_);
    273         if (!status.isOk()) {
    274             return ::testing::AssertionFailure() << "Could not create app data: "
    275                                                  << status.toString8().c_str();
    276         }
    277 
    278         // Create a secondary dex file on CE storage
    279         const char* volume_uuid_cstr = volume_uuid_ == nullptr ? nullptr : volume_uuid_->c_str();
    280         app_private_dir_ce_ = create_data_user_ce_package_path(
    281                 volume_uuid_cstr, kTestUserId, package_name_.c_str());
    282         secondary_dex_ce_ = app_private_dir_ce_ + "/secondary_ce.jar";
    283         if (!WriteBase64ToFile(kDexFile,
    284                                secondary_dex_ce_,
    285                                kTestAppUid,
    286                                kTestAppGid,
    287                                0600,
    288                                &error_msg)) {
    289             return ::testing::AssertionFailure() << "Could not write base64 file to "
    290                                                  << secondary_dex_ce_ << " : " << error_msg;
    291         }
    292         std::string app_private_dir_ce_link = create_data_user_ce_package_path_as_user_link(
    293                 volume_uuid_cstr, kTestUserId, package_name_.c_str());
    294         secondary_dex_ce_link_ = app_private_dir_ce_link + "/secondary_ce.jar";
    295 
    296         // Create a secondary dex file on DE storage.
    297         app_private_dir_de_ = create_data_user_de_package_path(
    298                 volume_uuid_cstr, kTestUserId, package_name_.c_str());
    299         secondary_dex_de_ = app_private_dir_de_ + "/secondary_de.jar";
    300         if (!WriteBase64ToFile(kDexFile,
    301                                secondary_dex_de_,
    302                                kTestAppUid,
    303                                kTestAppGid,
    304                                0600,
    305                                &error_msg)) {
    306             return ::testing::AssertionFailure() << "Could not write base64 file to "
    307                                                  << secondary_dex_de_ << " : " << error_msg;
    308         }
    309 
    310         // Fix app data uid.
    311         status = service_->fixupAppData(volume_uuid_, kTestUserId);
    312         if (!status.isOk()) {
    313             return ::testing::AssertionFailure() << "Could not fixup app data: "
    314                                                  << status.toString8().c_str();
    315         }
    316 
    317         return ::testing::AssertionSuccess();
    318     }
    319 
    320 
    321     std::string GetSecondaryDexArtifact(const std::string& path, const std::string& type) {
    322         std::string::size_type end = path.rfind('.');
    323         std::string::size_type start = path.rfind('/', end);
    324         return path.substr(0, start) + "/oat/" + kRuntimeIsa + "/" +
    325                 path.substr(start + 1, end - start) + type;
    326     }
    327 
    328     void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
    329             bool should_binder_call_succeed, bool should_dex_be_compiled = true,
    330             /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1,
    331             const char* class_loader_context = nullptr) {
    332         if (uid == -1) {
    333             uid = kTestAppUid;
    334         }
    335         if (class_loader_context == nullptr) {
    336             class_loader_context = "&";
    337         }
    338         std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
    339         int32_t dexopt_needed = 0;  // does not matter;
    340         std::unique_ptr<std::string> out_path = nullptr;  // does not matter
    341         int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
    342         std::string compiler_filter = "speed-profile";
    343         std::unique_ptr<std::string> class_loader_context_ptr(
    344                 new std::string(class_loader_context));
    345         std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
    346         bool downgrade = false;
    347         int32_t target_sdk_version = 0;  // default
    348         std::unique_ptr<std::string> profile_name_ptr = nullptr;
    349         std::unique_ptr<std::string> dm_path_ptr = nullptr;
    350         std::unique_ptr<std::string> compilation_reason_ptr = nullptr;
    351 
    352         binder::Status result = service_->dexopt(path,
    353                                                  uid,
    354                                                  package_name_ptr,
    355                                                  kRuntimeIsa,
    356                                                  dexopt_needed,
    357                                                  out_path,
    358                                                  dex_flags,
    359                                                  compiler_filter,
    360                                                  volume_uuid_,
    361                                                  class_loader_context_ptr,
    362                                                  se_info_ptr,
    363                                                  downgrade,
    364                                                  target_sdk_version,
    365                                                  profile_name_ptr,
    366                                                  dm_path_ptr,
    367                                                  compilation_reason_ptr);
    368         ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
    369         int expected_access = should_dex_be_compiled ? 0 : -1;
    370         std::string odex = GetSecondaryDexArtifact(path, "odex");
    371         std::string vdex = GetSecondaryDexArtifact(path, "vdex");
    372         std::string art = GetSecondaryDexArtifact(path, "art");
    373         ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
    374         ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
    375         ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
    376         if (binder_result != nullptr) {
    377             *binder_result = result;
    378         }
    379     }
    380 
    381     void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
    382             bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
    383             int32_t uid = -1, std::string* package_override = nullptr) {
    384         if (uid == -1) {
    385             uid = kTestAppUid;
    386         }
    387         std::vector<std::string> isas;
    388         isas.push_back(kRuntimeIsa);
    389         bool out_secondary_dex_exists = false;
    390         binder::Status result = service_->reconcileSecondaryDexFile(
    391             path,
    392             package_override == nullptr ? package_name_ : *package_override,
    393             uid,
    394             isas,
    395             volume_uuid_,
    396             storage_flag,
    397             &out_secondary_dex_exists);
    398 
    399         ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
    400         ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
    401 
    402         int expected_access = should_dex_be_deleted ? -1 : 0;
    403         std::string odex = GetSecondaryDexArtifact(path, "odex");
    404         std::string vdex = GetSecondaryDexArtifact(path, "vdex");
    405         std::string art = GetSecondaryDexArtifact(path, "art");
    406         ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
    407         ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
    408         ASSERT_EQ(-1, access(art.c_str(), R_OK));  // empty profiles do not generate an image.
    409     }
    410 
    411     void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
    412         struct stat st;
    413         ASSERT_EQ(0, stat(file.c_str(), &st));
    414         ASSERT_EQ(uid, st.st_uid);
    415         ASSERT_EQ(gid, st.st_gid);
    416         ASSERT_EQ(mode, st.st_mode);
    417     }
    418 
    419     void CompilePrimaryDexOk(std::string compiler_filter,
    420                              int32_t dex_flags,
    421                              const char* oat_dir,
    422                              int32_t uid,
    423                              int32_t dexopt_needed,
    424                              binder::Status* binder_result = nullptr,
    425                              const char* dm_path = nullptr,
    426                              bool downgrade = false) {
    427         CompilePrimaryDex(compiler_filter,
    428                           dex_flags,
    429                           oat_dir,
    430                           uid,
    431                           dexopt_needed,
    432                           dm_path,
    433                           downgrade,
    434                           true,
    435                           binder_result);
    436     }
    437 
    438     void CompilePrimaryDexFail(std::string compiler_filter,
    439                                int32_t dex_flags,
    440                                const char* oat_dir,
    441                                int32_t uid,
    442                                int32_t dexopt_needed,
    443                                binder::Status* binder_result = nullptr,
    444                                const char* dm_path = nullptr,
    445                                bool downgrade = false) {
    446         CompilePrimaryDex(compiler_filter,
    447                           dex_flags,
    448                           oat_dir,
    449                           uid,
    450                           dexopt_needed,
    451                           dm_path,
    452                           downgrade,
    453                           false,
    454                           binder_result);
    455     }
    456 
    457     void CompilePrimaryDex(std::string compiler_filter,
    458                            int32_t dex_flags,
    459                            const char* oat_dir,
    460                            int32_t uid,
    461                            int32_t dexopt_needed,
    462                            const char* dm_path,
    463                            bool downgrade,
    464                            bool should_binder_call_succeed,
    465                            /*out */ binder::Status* binder_result) {
    466         std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
    467         std::unique_ptr<std::string> out_path(
    468                 oat_dir == nullptr ? nullptr : new std::string(oat_dir));
    469         std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
    470         std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
    471         int32_t target_sdk_version = 0;  // default
    472         std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
    473         std::unique_ptr<std::string> dm_path_ptr = nullptr;
    474         if (dm_path != nullptr) {
    475             dm_path_ptr.reset(new std::string(dm_path));
    476         }
    477         std::unique_ptr<std::string> compilation_reason_ptr(new std::string("test-reason"));
    478 
    479         bool prof_result;
    480         ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
    481                 package_name_, kTestUserId, kTestAppId, *profile_name_ptr, apk_path_,
    482                 /*dex_metadata*/ nullptr, &prof_result));
    483         ASSERT_TRUE(prof_result);
    484 
    485         binder::Status result = service_->dexopt(apk_path_,
    486                                                  uid,
    487                                                  package_name_ptr,
    488                                                  kRuntimeIsa,
    489                                                  dexopt_needed,
    490                                                  out_path,
    491                                                  dex_flags,
    492                                                  compiler_filter,
    493                                                  volume_uuid_,
    494                                                  class_loader_context_ptr,
    495                                                  se_info_ptr,
    496                                                  downgrade,
    497                                                  target_sdk_version,
    498                                                  profile_name_ptr,
    499                                                  dm_path_ptr,
    500                                                  compilation_reason_ptr);
    501         ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
    502 
    503         if (!should_binder_call_succeed) {
    504             if (binder_result != nullptr) {
    505                 *binder_result = result;
    506             }
    507             return;
    508         }
    509         // Check the access to the compiler output.
    510         //  - speed-profile artifacts are not world-wide readable.
    511         //  - files are owned by the system uid.
    512         std::string odex = GetPrimaryDexArtifact(oat_dir, apk_path_, "odex");
    513         std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
    514         std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
    515 
    516         bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
    517         mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
    518         CheckFileAccess(odex, kSystemUid, uid, mode);
    519         CheckFileAccess(vdex, kSystemUid, uid, mode);
    520 
    521         if (compiler_filter == "speed-profile") {
    522             CheckFileAccess(art, kSystemUid, uid, mode);
    523         }
    524         if (binder_result != nullptr) {
    525             *binder_result = result;
    526         }
    527     }
    528 
    529     std::string GetPrimaryDexArtifact(const char* oat_dir,
    530                                       const std::string& dex_path,
    531                                       const std::string& type) {
    532         if (oat_dir == nullptr) {
    533             std::string path = dex_path;
    534             for (auto it = path.begin() + 1; it < path.end(); ++it) {
    535                 if (*it == '/') {
    536                     *it = '@';
    537                 }
    538             }
    539             return android_data_dir + DALVIK_CACHE + '/' + kRuntimeIsa + "/" + path
    540                     + "@classes.dex";
    541         } else {
    542             std::string::size_type name_end = dex_path.rfind('.');
    543             std::string::size_type name_start = dex_path.rfind('/');
    544             return std::string(oat_dir) + "/" + kRuntimeIsa + "/" +
    545                     dex_path.substr(name_start + 1, name_end - name_start) + type;
    546         }
    547     }
    548 };
    549 
    550 
    551 TEST_F(DexoptTest, DexoptSecondaryCe) {
    552     LOG(INFO) << "DexoptSecondaryCe";
    553     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
    554         /*binder_ok*/ true, /*compile_ok*/ true);
    555 }
    556 
    557 TEST_F(DexoptTest, DexoptSecondaryCeLink) {
    558     LOG(INFO) << "DexoptSecondaryCeLink";
    559     CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
    560         /*binder_ok*/ true, /*compile_ok*/ true);
    561 }
    562 
    563 TEST_F(DexoptTest, DexoptSecondaryCeWithContext) {
    564     LOG(INFO) << "DexoptSecondaryCeWithContext";
    565     std::string class_loader_context = "PCL[" + secondary_dex_ce_ + "]";
    566     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
    567         /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
    568 }
    569 
    570 TEST_F(DexoptTest, DexoptSecondaryDe) {
    571     LOG(INFO) << "DexoptSecondaryDe";
    572     CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
    573         /*binder_ok*/ true, /*compile_ok*/ true);
    574 }
    575 
    576 TEST_F(DexoptTest, DexoptSecondaryDeWithContext) {
    577     LOG(INFO) << "DexoptSecondaryDeWithContext";
    578     std::string class_loader_context = "PCL[" + secondary_dex_de_ + "]";
    579     CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
    580         /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
    581 }
    582 
    583 TEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
    584     LOG(INFO) << "DexoptSecondaryDoesNotExist";
    585     // If the file validates but does not exist we do not treat it as an error.
    586     binder::Status status;
    587     CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
    588         /*binder_ok*/ true,  /*compile_ok*/ false, &status);
    589     EXPECT_STREQ(status.toString8().c_str(), "No error");
    590 }
    591 
    592 TEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
    593     LOG(INFO) << "DexoptSecondaryStorageValidationError";
    594     binder::Status status;
    595     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
    596         /*binder_ok*/ false,  /*compile_ok*/ false, &status);
    597     EXPECT_STREQ(status.toString8().c_str(),
    598                  "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
    599 }
    600 
    601 TEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
    602     LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
    603     binder::Status status;
    604     CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
    605         /*binder_ok*/ false,  /*compile_ok*/ false, &status);
    606     EXPECT_STREQ(status.toString8().c_str(),
    607                  "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
    608 }
    609 
    610 TEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
    611     LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
    612     binder::Status status;
    613     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
    614         /*binder_ok*/ false,  /*compile_ok*/ false, &status, kSystemUid);
    615     EXPECT_STREQ(status.toString8().c_str(),
    616                  "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer open zip failed'");
    617 }
    618 
    619 TEST_F(DexoptTest, DexoptPrimaryPublic) {
    620     LOG(INFO) << "DexoptPrimaryPublic";
    621     CompilePrimaryDexOk("verify",
    622                         DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
    623                         app_oat_dir_.c_str(),
    624                         kTestAppGid,
    625                         DEX2OAT_FROM_SCRATCH);
    626 }
    627 
    628 TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
    629     LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
    630     binder::Status status;
    631     CompilePrimaryDexFail("awesome-filter",
    632                           DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
    633                           app_oat_dir_.c_str(),
    634                           kTestAppGid,
    635                           DEX2OAT_FROM_SCRATCH,
    636                           &status);
    637     EXPECT_STREQ(status.toString8().c_str(),
    638                  "Status(-8, EX_SERVICE_SPECIFIC): \'256: Dex2oat invocation for "
    639                  "/data/app/com.installd.test.dexopt/base.jar failed: unspecified dex2oat error'");
    640 }
    641 
    642 TEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
    643     LOG(INFO) << "DexoptPrimaryProfileNonPublic";
    644     CompilePrimaryDexOk("speed-profile",
    645                         DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_GENERATE_APP_IMAGE,
    646                         app_oat_dir_.c_str(),
    647                         kTestAppGid,
    648                         DEX2OAT_FROM_SCRATCH);
    649 }
    650 
    651 TEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
    652     LOG(INFO) << "DexoptPrimaryProfilePublic";
    653     CompilePrimaryDexOk("speed-profile",
    654                         DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC |
    655                                 DEXOPT_GENERATE_APP_IMAGE,
    656                         app_oat_dir_.c_str(),
    657                         kTestAppGid,
    658                         DEX2OAT_FROM_SCRATCH);
    659 }
    660 
    661 TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
    662     LOG(INFO) << "DexoptPrimaryBackgroundOk";
    663     CompilePrimaryDexOk("speed-profile",
    664                         DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
    665                                 DEXOPT_GENERATE_APP_IMAGE,
    666                         app_oat_dir_.c_str(),
    667                         kTestAppGid,
    668                         DEX2OAT_FROM_SCRATCH);
    669 }
    670 
    671 TEST_F(DexoptTest, ResolveStartupConstStrings) {
    672     LOG(INFO) << "DexoptDex2oatResolveStartupStrings";
    673     const std::string property = "persist.device_config.runtime.dex2oat_resolve_startup_strings";
    674     const std::string previous_value = android::base::GetProperty(property, "");
    675     auto restore_property = android::base::make_scope_guard([=]() {
    676         android::base::SetProperty(property, previous_value);
    677     });
    678     std::string odex = GetPrimaryDexArtifact(app_oat_dir_.c_str(), apk_path_, "odex");
    679     // Disable the property to start.
    680     bool found_disable = false;
    681     ASSERT_TRUE(android::base::SetProperty(property, "false")) << property;
    682     CompilePrimaryDexOk("speed-profile",
    683                         DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
    684                                 DEXOPT_GENERATE_APP_IMAGE,
    685                         app_oat_dir_.c_str(),
    686                         kTestAppGid,
    687                         DEX2OAT_FROM_SCRATCH);
    688     run_cmd_and_process_output(
    689             "oatdump --header-only --oat-file=" + odex,
    690             [&](const std::string& line) {
    691         if (line.find("--resolve-startup-const-strings=false") != std::string::npos) {
    692             found_disable = true;
    693         }
    694     });
    695     EXPECT_TRUE(found_disable);
    696     // Enable the property and inspect that .art artifact is larger.
    697     bool found_enable = false;
    698     ASSERT_TRUE(android::base::SetProperty(property, "true")) << property;
    699     CompilePrimaryDexOk("speed-profile",
    700                         DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
    701                                 DEXOPT_GENERATE_APP_IMAGE,
    702                         app_oat_dir_.c_str(),
    703                         kTestAppGid,
    704                         DEX2OAT_FROM_SCRATCH);
    705     run_cmd_and_process_output(
    706             "oatdump --header-only --oat-file=" + odex,
    707             [&](const std::string& line) {
    708         if (line.find("--resolve-startup-const-strings=true") != std::string::npos) {
    709             found_enable = true;
    710         }
    711     });
    712     EXPECT_TRUE(found_enable);
    713 }
    714 
    715 class PrimaryDexReCompilationTest : public DexoptTest {
    716   public:
    717     virtual void SetUp() {
    718         DexoptTest::SetUp();
    719         CompilePrimaryDexOk("verify",
    720                             DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
    721                             app_oat_dir_.c_str(),
    722                             kTestAppGid,
    723                             DEX2OAT_FROM_SCRATCH);
    724         std::string odex = GetSecondaryDexArtifact(apk_path_, "odex");
    725         std::string vdex = GetSecondaryDexArtifact(apk_path_, "vdex");
    726 
    727         first_compilation_odex_fd_.reset(open(odex.c_str(), O_RDONLY));
    728         first_compilation_vdex_fd_.reset(open(vdex.c_str(), O_RDONLY));
    729     }
    730 
    731     virtual void TearDown() {
    732         first_compilation_odex_fd_.reset(-1);
    733         first_compilation_vdex_fd_.reset(-1);
    734         DexoptTest::TearDown();
    735     }
    736 
    737   protected:
    738     unique_fd first_compilation_odex_fd_;
    739     unique_fd first_compilation_vdex_fd_;
    740 };
    741 
    742 TEST_F(PrimaryDexReCompilationTest, DexoptPrimaryUpdateInPlaceVdex) {
    743     LOG(INFO) << "DexoptPrimaryUpdateInPlaceVdex";
    744 
    745     CompilePrimaryDexOk("verify",
    746                         DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
    747                         app_oat_dir_.c_str(),
    748                         kTestAppGid,
    749                         DEX2OAT_FOR_BOOT_IMAGE);
    750 }
    751 
    752 class ReconcileTest : public DexoptTest {
    753     virtual void SetUp() {
    754         DexoptTest::SetUp();
    755         CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
    756             /*binder_ok*/ true, /*compile_ok*/ true);
    757         CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
    758             /*binder_ok*/ true, /*compile_ok*/ true);
    759     }
    760 };
    761 
    762 TEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
    763     LOG(INFO) << "ReconcileSecondaryCeExists";
    764     reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
    765         /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
    766 }
    767 
    768 TEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
    769     LOG(INFO) << "ReconcileSecondaryCeLinkExists";
    770     reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
    771         /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
    772 }
    773 
    774 TEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
    775     LOG(INFO) << "ReconcileSecondaryDeExists";
    776     reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
    777         /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
    778 }
    779 
    780 TEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
    781     LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
    782     run_cmd("rm -rf " + secondary_dex_de_);
    783     reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
    784         /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
    785 }
    786 
    787 TEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
    788     // Validation errors will not clean the odex/vdex/art files but will mark
    789     // the file as non existent so that the PM knows it should purge it from its
    790     // records.
    791     LOG(INFO) << "ReconcileSecondaryStorageValidationError";
    792     reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
    793         /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
    794 }
    795 
    796 TEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
    797     LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
    798     // Attempt to reconcile the dex files of the test app from a different app.
    799     std::string another_app = "another.app";
    800     reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
    801         /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
    802 }
    803 
    804 TEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
    805     LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
    806     reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
    807         /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
    808 }
    809 
    810 class ProfileTest : public DexoptTest {
    811   protected:
    812     std::string cur_profile_;
    813     std::string ref_profile_;
    814     std::string snap_profile_;
    815 
    816     static constexpr const char* kPrimaryProfile = "primary.prof";
    817 
    818     virtual void SetUp() {
    819         DexoptTest::SetUp();
    820         cur_profile_ = create_current_profile_path(
    821                 kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
    822         ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
    823                 /*is_secondary_dex*/ false);
    824         snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
    825     }
    826 
    827     void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
    828             int32_t num_dex) {
    829         run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
    830                 " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
    831                 " --generate-test-profile=" + path);
    832         ::chmod(path.c_str(), mode);
    833         ::chown(path.c_str(), uid, gid);
    834     }
    835 
    836     void SetupProfiles(bool setup_ref) {
    837         SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
    838         if (setup_ref) {
    839             SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
    840         }
    841     }
    842 
    843     void createProfileSnapshot(int32_t appid, const std::string& package_name,
    844             bool expected_result) {
    845         bool result;
    846         ASSERT_BINDER_SUCCESS(service_->createProfileSnapshot(
    847                 appid, package_name, kPrimaryProfile, apk_path_, &result));
    848         ASSERT_EQ(expected_result, result);
    849 
    850         if (!expected_result) {
    851             // Do not check the files if we expect to fail.
    852             return;
    853         }
    854 
    855         // Check that the snapshot was created witht he expected acess flags.
    856         CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
    857 
    858         // The snapshot should be equivalent to the merge of profiles.
    859         std::string expected_profile_content = snap_profile_ + ".expected";
    860         run_cmd("rm -f " + expected_profile_content);
    861         run_cmd("touch " + expected_profile_content);
    862         run_cmd("profman --profile-file=" + cur_profile_ +
    863                 " --profile-file=" + ref_profile_ +
    864                 " --reference-profile-file=" + expected_profile_content +
    865                 " --apk=" + apk_path_);
    866 
    867         ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
    868 
    869         pid_t pid = fork();
    870         if (pid == 0) {
    871             /* child */
    872             TransitionToSystemServer();
    873 
    874             // System server should be able to open the the spanshot.
    875             unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
    876             ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
    877             _exit(0);
    878         }
    879         /* parent */
    880         ASSERT_TRUE(WIFEXITED(wait_child(pid)));
    881     }
    882 
    883     void mergePackageProfiles(const std::string& package_name,
    884                               const std::string& code_path,
    885                               bool expected_result) {
    886         bool result;
    887         ASSERT_BINDER_SUCCESS(service_->mergeProfiles(
    888                 kTestAppUid, package_name, code_path, &result));
    889         ASSERT_EQ(expected_result, result);
    890 
    891         if (!expected_result) {
    892             // Do not check the files if we expect to fail.
    893             return;
    894         }
    895 
    896         // Check that the snapshot was created witht he expected acess flags.
    897         CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
    898 
    899         // The snapshot should be equivalent to the merge of profiles.
    900         std::string ref_profile_content = ref_profile_ + ".expected";
    901         run_cmd("rm -f " + ref_profile_content);
    902         run_cmd("touch " + ref_profile_content);
    903         run_cmd("profman --profile-file=" + cur_profile_ +
    904                 " --profile-file=" + ref_profile_ +
    905                 " --reference-profile-file=" + ref_profile_content);
    906 
    907         ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
    908     }
    909 
    910     // TODO(calin): add dex metadata tests once the ART change is merged.
    911     void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
    912             bool expected_result) {
    913         bool result;
    914         ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
    915                 package_name, kTestUserId, kTestAppId, profile_name, apk_path_,
    916                 /*dex_metadata*/ nullptr, &result));
    917         ASSERT_EQ(expected_result, result);
    918 
    919         if (!expected_result) {
    920             // Do not check the files if we expect to fail.
    921             return;
    922         }
    923 
    924         std::string code_path_cur_prof = create_current_profile_path(
    925                 kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
    926         std::string code_path_ref_profile = create_reference_profile_path(package_name,
    927                 profile_name, /*is_secondary_dex*/ false);
    928 
    929         // Check that we created the current profile.
    930         CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
    931 
    932         // Without dex metadata we don't generate a reference profile.
    933         ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
    934     }
    935 
    936   protected:
    937     void TransitionToSystemServer() {
    938         ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
    939         int32_t res = selinux_android_setcon("u:r:system_server:s0");
    940         ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
    941     }
    942 
    943     bool AreFilesEqual(const std::string& file1, const std::string& file2) {
    944         std::vector<uint8_t> content1;
    945         std::vector<uint8_t> content2;
    946 
    947         if (!ReadAll(file1, &content1)) return false;
    948         if (!ReadAll(file2, &content2)) return false;
    949         return content1 == content2;
    950     }
    951 
    952     bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
    953         unique_fd fd(open(file.c_str(), O_RDONLY));
    954         if (fd < 0) {
    955             PLOG(ERROR) << "Failed to open " << file;
    956             return false;
    957         }
    958         struct stat st;
    959         if (fstat(fd, &st) != 0) {
    960             PLOG(ERROR) << "Failed to stat " << file;
    961             return false;
    962         }
    963         content->resize(st.st_size);
    964         bool result = ReadFully(fd, content->data(), content->size());
    965         if (!result) {
    966             PLOG(ERROR) << "Failed to read " << file;
    967         }
    968         return result;
    969     }
    970 };
    971 
    972 TEST_F(ProfileTest, ProfileSnapshotOk) {
    973     LOG(INFO) << "ProfileSnapshotOk";
    974 
    975     SetupProfiles(/*setup_ref*/ true);
    976     createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
    977 }
    978 
    979 // The reference profile is created on the fly. We need to be able to
    980 // snapshot without one.
    981 TEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
    982     LOG(INFO) << "ProfileSnapshotOkNoReference";
    983 
    984     SetupProfiles(/*setup_ref*/ false);
    985     createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
    986 }
    987 
    988 TEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
    989     LOG(INFO) << "ProfileSnapshotFailWrongPackage";
    990 
    991     SetupProfiles(/*setup_ref*/ true);
    992     createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
    993 }
    994 
    995 TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
    996     LOG(INFO) << "ProfileSnapshotDestroySnapshot";
    997 
    998     SetupProfiles(/*setup_ref*/ true);
    999     createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
   1000 
   1001     ASSERT_BINDER_SUCCESS(service_->destroyProfileSnapshot(package_name_, kPrimaryProfile));
   1002     struct stat st;
   1003     ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
   1004     ASSERT_EQ(ENOENT, errno);
   1005 }
   1006 
   1007 TEST_F(ProfileTest, ProfileMergeOk) {
   1008     LOG(INFO) << "ProfileMergeOk";
   1009 
   1010     SetupProfiles(/*setup_ref*/ true);
   1011     mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
   1012 }
   1013 
   1014 // The reference profile is created on the fly. We need to be able to
   1015 // merge without one.
   1016 TEST_F(ProfileTest, ProfileMergeOkNoReference) {
   1017     LOG(INFO) << "ProfileMergeOkNoReference";
   1018 
   1019     SetupProfiles(/*setup_ref*/ false);
   1020     mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
   1021 }
   1022 
   1023 TEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
   1024     LOG(INFO) << "ProfileMergeFailWrongPackage";
   1025 
   1026     SetupProfiles(/*setup_ref*/ true);
   1027     mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
   1028 }
   1029 
   1030 TEST_F(ProfileTest, ProfileDirOk) {
   1031     LOG(INFO) << "ProfileDirOk";
   1032 
   1033     std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
   1034             kTestUserId, package_name_);
   1035     std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
   1036             kPrimaryProfile, /*is_secondary_dex*/false);
   1037     std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
   1038 
   1039     CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
   1040     CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
   1041 }
   1042 
   1043 // Verify that the profile directories are fixed up during an upgrade.
   1044 // (The reference profile directory is prepared lazily).
   1045 TEST_F(ProfileTest, ProfileDirOkAfterFixup) {
   1046     LOG(INFO) << "ProfileDirOkAfterFixup";
   1047 
   1048     std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
   1049             kTestUserId, package_name_);
   1050     std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
   1051             kPrimaryProfile, /*is_secondary_dex*/false);
   1052     std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
   1053 
   1054     // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
   1055     ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
   1056     ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
   1057 
   1058     // Run createAppData again which will offer to fix-up the profile directories.
   1059     ASSERT_BINDER_SUCCESS(service_->createAppData(
   1060             volume_uuid_,
   1061             package_name_,
   1062             kTestUserId,
   1063             kAppDataFlags,
   1064             kTestAppUid,
   1065             se_info_,
   1066             kOSdkVersion,
   1067             &ce_data_inode_));
   1068 
   1069     // Check the file access.
   1070     CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
   1071     CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
   1072 }
   1073 
   1074 TEST_F(ProfileTest, ProfilePrepareOk) {
   1075     LOG(INFO) << "ProfilePrepareOk";
   1076     preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
   1077 }
   1078 
   1079 TEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
   1080     LOG(INFO) << "ProfilePrepareFailInvalidPackage";
   1081     preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
   1082 }
   1083 
   1084 TEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
   1085     LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
   1086     SetupProfiles(/*setup_ref*/ false);
   1087     // Change the uid on the profile to trigger a failure.
   1088     ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
   1089     preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
   1090 }
   1091 
   1092 
   1093 class BootProfileTest : public ProfileTest {
   1094   public:
   1095     virtual void setup() {
   1096         ProfileTest::SetUp();
   1097         intial_android_profiles_dir = android_profiles_dir;
   1098     }
   1099 
   1100     virtual void TearDown() {
   1101         android_profiles_dir = intial_android_profiles_dir;
   1102         ProfileTest::TearDown();
   1103     }
   1104 
   1105     void UpdateAndroidProfilesDir(const std::string& profile_dir) {
   1106         android_profiles_dir = profile_dir;
   1107         // We need to create the reference profile directory in the new profile dir.
   1108         run_cmd("mkdir -p " + profile_dir + "/ref");
   1109     }
   1110 
   1111     void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
   1112         bool result;
   1113         ASSERT_BINDER_SUCCESS(service_->createProfileSnapshot(
   1114                 -1, "android", "android.prof", classpath, &result));
   1115         ASSERT_EQ(expected_result, result);
   1116 
   1117         if (!expected_result) {
   1118             // Do not check the files if we expect to fail.
   1119             return;
   1120         }
   1121 
   1122         // Check that the snapshot was created with he expected access flags.
   1123         const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
   1124         CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
   1125 
   1126         pid_t pid = fork();
   1127         if (pid == 0) {
   1128             /* child */
   1129             TransitionToSystemServer();
   1130 
   1131             // System server should be able to open the snapshot.
   1132             unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
   1133             ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
   1134             _exit(0);
   1135         }
   1136         /* parent */
   1137         ASSERT_TRUE(WIFEXITED(wait_child(pid)));
   1138     }
   1139   protected:
   1140     std::string intial_android_profiles_dir;
   1141 };
   1142 
   1143 TEST_F(BootProfileTest, BootProfileSnapshotOk) {
   1144     LOG(INFO) << "BootProfileSnapshotOk";
   1145     char* boot_classpath = getenv("BOOTCLASSPATH");
   1146     ASSERT_TRUE(boot_classpath != nullptr);
   1147     createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
   1148 }
   1149 
   1150 TEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
   1151     LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
   1152 
   1153     createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
   1154 }
   1155 
   1156 TEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
   1157     LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
   1158     char* boot_classpath = getenv("BOOTCLASSPATH");
   1159     ASSERT_TRUE(boot_classpath != nullptr);
   1160 
   1161     // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
   1162     // Still, this is not a failure case.
   1163     UpdateAndroidProfilesDir(app_apk_dir_);
   1164     createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
   1165 }
   1166 
   1167 // Verify that profile collection.
   1168 TEST_F(BootProfileTest, CollectProfiles) {
   1169     LOG(INFO) << "CollectProfiles";
   1170 
   1171     // Create some profile directories mimicking the real profile structure.
   1172     run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
   1173     run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
   1174     run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
   1175     // Create an empty profile.
   1176     run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
   1177     // Create a random file.
   1178     run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
   1179 
   1180     // Create some non-empty profiles.
   1181     std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
   1182     run_cmd("echo 1 > " + current_prof);
   1183     std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
   1184     run_cmd("echo 1 > " + ref_prof);
   1185 
   1186     UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
   1187 
   1188     std::vector<std::string> profiles;
   1189     collect_profiles(&profiles);
   1190 
   1191     // Only two profiles should be in the output.
   1192     ASSERT_EQ(2u, profiles.size());
   1193     ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
   1194     ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
   1195 }
   1196 
   1197 TEST_F(DexoptTest, select_execution_binary) {
   1198     LOG(INFO) << "DexoptTestselect_execution_binary";
   1199 
   1200     std::string release_str = app_private_dir_ce_  + "/release";
   1201     std::string debug_str = app_private_dir_ce_  + "/debug";
   1202 
   1203     // Setup the binaries. Note that we only need executable files to actually
   1204     // test the execution binary selection
   1205     run_cmd("touch " + release_str);
   1206     run_cmd("touch " + debug_str);
   1207     run_cmd("chmod 777 " + release_str);
   1208     run_cmd("chmod 777 " + debug_str);
   1209 
   1210     const char* release = release_str.c_str();
   1211     const char* debug = debug_str.c_str();
   1212 
   1213     ASSERT_STREQ(release, select_execution_binary(
   1214         release,
   1215         debug,
   1216         /*background_job_compile=*/ false,
   1217         /*is_debug_runtime=*/ false,
   1218         /*is_release=*/ false,
   1219         /*is_debuggable_build=*/ false));
   1220 
   1221     ASSERT_STREQ(release, select_execution_binary(
   1222         release,
   1223         debug,
   1224         /*background_job_compile=*/ true,
   1225         /*is_debug_runtime=*/ false,
   1226         /*is_release=*/ true,
   1227         /*is_debuggable_build=*/ true));
   1228 
   1229     ASSERT_STREQ(debug, select_execution_binary(
   1230         release,
   1231         debug,
   1232         /*background_job_compile=*/ false,
   1233         /*is_debug_runtime=*/ true,
   1234         /*is_release=*/ false,
   1235         /*is_debuggable_build=*/ false));
   1236 
   1237     ASSERT_STREQ(debug, select_execution_binary(
   1238         release,
   1239         debug,
   1240         /*background_job_compile=*/ true,
   1241         /*is_debug_runtime=*/ false,
   1242         /*is_release=*/ false,
   1243         /*is_debuggable_build=*/ true));
   1244 
   1245 
   1246     // Select the release when the debug file is not there.
   1247     ASSERT_STREQ(release, select_execution_binary(
   1248         release,
   1249         "does_not_exist",
   1250         /*background_job_compile=*/ false,
   1251         /*is_debug_runtime=*/ true,
   1252         /*is_release=*/ false,
   1253         /*is_debuggable_build=*/ false));
   1254 }
   1255 
   1256 }  // namespace installd
   1257 }  // namespace android
   1258