/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <HalInterfaces.h>
#include <SampleDriver.h>
#include <gtest/gtest.h>

#include <string>
#include <vector>

#include "AppInfoFetcher.h"
#include "HalUtils.h"
#include "Manager.h"
#include "NeuralNetworks.h"
#include "NeuralNetworksExtensions.h"
#include "TypeManager.h"

namespace {

using DeviceManager = ::android::nn::DeviceManager;
using SampleDriver = ::android::nn::sample_driver::SampleDriver;
using TypeManager = ::android::nn::TypeManager;

namespace hardware = ::android::hardware;
namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;
namespace V1_3 = ::android::hardware::neuralnetworks::V1_3;

const char* kTestDriverName = "extensions-test-driver";
const char* kTestExtension1 = "vendor.test.one";
const char* kTestExtension2 = "vendor.test.two";
const char* kTestExtension3 = "vendor.test.three";

class TestDriver : public SampleDriver {
   public:
    TestDriver() : SampleDriver(kTestDriverName) {}
    ~TestDriver() override {}

    hardware::Return<void> getSupportedExtensions(getSupportedExtensions_cb cb) override {
        cb(V1_0::ErrorStatus::NONE, {
                                            {.name = kTestExtension1},
                                            {.name = kTestExtension2},
                                            {.name = kTestExtension3},
                                    });
        return hardware::Void();
    }

    hardware::Return<void> getCapabilities_1_3(getCapabilities_1_3_cb cb) override {
        cb(V1_3::ErrorStatus::NONE, ::android::nn::makeCapabilities(1.0));
        return hardware::Void();
    }

    hardware::Return<void> getSupportedOperations_1_3(const V1_3::Model&,
                                                      getSupportedOperations_1_3_cb) override {
        CHECK(false) << "not implemented";
        return hardware::Void();
    }
};

class ExtensionsTest : public ::testing::Test {
   protected:
    virtual void SetUp() {
        // This is needed before we have the CPU fallback path being treated as a Device.
        if (DeviceManager::get()->getUseCpuOnly()) {
            GTEST_SKIP();
        }

        DeviceManager::get()->forTest_registerDevice(
                android::nn::makeSharedDevice(kTestDriverName, new TestDriver()));
        // Discover extensions provided by registered devices.
        TypeManager::get()->forTest_reset();
        mDevice = getDeviceByName(kTestDriverName);
        ASSERT_NE(mDevice, nullptr);
    }

    virtual void TearDown() {
        DeviceManager::get()->forTest_reInitializeDeviceList();
        TypeManager::get()->forTest_reset();
    }

    ANeuralNetworksDevice* getDeviceByName(const std::string& name) {
        ANeuralNetworksDevice* result = nullptr;
        uint32_t numDevices = 0;
        EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
        EXPECT_GE(numDevices, 1u);
        for (uint32_t i = 0; i < numDevices; i++) {
            ANeuralNetworksDevice* device = nullptr;
            EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
            const char* buffer = nullptr;
            EXPECT_EQ(ANeuralNetworksDevice_getName(device, &buffer), ANEURALNETWORKS_NO_ERROR);
            if (name.compare(buffer) == 0) {
                EXPECT_EQ(result, nullptr) << "multiple devices named " << name;
                result = device;
            }
        }
        return result;
    }

    bool testDriverSupportsExtension(const char* extensionName) {
        bool result;
        EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(mDevice, extensionName, &result),
                  ANEURALNETWORKS_NO_ERROR);
        return result;
    }

   private:
    ANeuralNetworksDevice* mDevice;
};

TEST_F(ExtensionsTest, DeviceReportsSupportedExtensions) {
    EXPECT_TRUE(testDriverSupportsExtension(kTestExtension1));
    EXPECT_FALSE(testDriverSupportsExtension("vendor.test.unknown"));
    EXPECT_FALSE(testDriverSupportsExtension("asdfasdfas"));
    EXPECT_TRUE(testDriverSupportsExtension(kTestExtension2));
    EXPECT_TRUE(testDriverSupportsExtension(kTestExtension3));
}

TEST_F(ExtensionsTest, TestAllowedNativeBinaries) {
    std::vector<std::string> allowlist = {"/data/foo",    "/vendor/foo",         "/odm/foo",
                                          "/product/foo", "/system/allowlisted", "/foobar/foo"};

    auto native_info = [&](const std::string& binaryPath) -> android::nn::AppInfoFetcher::AppInfo {
        return {.binaryPath = binaryPath,
                .appPackageName = "",
                .appIsSystemApp = false,
                .appIsOnVendorImage = false,
                .appIsOnProductImage = false};
    };

    // No binary info
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info(""),
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    // Non-approved top-level dir
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/foobar/foo"),
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    // Allowlisted /data binary
    EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/data/foo"),
                                                    /* useOnProductImageEnabled = */ false,
                                                    allowlist));
    // Allowlisted /vendor binary
    EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/vendor/foo"),
                                                    /* useOnProductImageEnabled = */ false,
                                                    allowlist));
    // Allowlisted /odm binary
    EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/odm/foo"),
                                                    /* useOnProductImageEnabled = */ false,
                                                    allowlist));
    // Non-allowlisted /system binary
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/system/foo"),
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    // allowlisted /system binary (can't be allowlisted)
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/system/allowlisted"),
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    // Allowlisted /product binary, product disabled
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed(native_info("/product/foo"),
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    // Allowlisted /product binary, product enabled
    EXPECT_TRUE(TypeManager::isExtensionsUseAllowed(native_info("/product/foo"),
                                                    /* useOnProductImageEnabled = */ true,
                                                    allowlist));

    // Allowlist for vendor/data partiion is not present on Android S.
    // Before S, checks below will fail. On S and later they will succeed.
    bool disableProductAllowlist = android_get_device_api_level() >= __ANDROID_API_S__;

    // Non-allowlisted /product binary, product enabled
    EXPECT_EQ(TypeManager::isExtensionsUseAllowed(native_info("/product/foo_not_allowlisted"),
                                                  /* useOnProductImageEnabled = */ true, allowlist),
              disableProductAllowlist);
    // Non-allowlisted /odm binary
    EXPECT_EQ(
            TypeManager::isExtensionsUseAllowed(native_info("/odm/foo_not_allowlisted"),
                                                /* useOnProductImageEnabled = */ false, allowlist),
            disableProductAllowlist);
    // Non-allowlisted /vendor binary
    EXPECT_EQ(
            TypeManager::isExtensionsUseAllowed(native_info("/vendor/foo_not_allowlisted"),
                                                /* useOnProductImageEnabled = */ false, allowlist),
            disableProductAllowlist);
    // Non-allowlisted /data binary
    EXPECT_EQ(
            TypeManager::isExtensionsUseAllowed(native_info("/data/foo_not_allowlisted"),
                                                /* useOnProductImageEnabled = */ false, allowlist),
            disableProductAllowlist);
}

TEST_F(ExtensionsTest, TestAllowedApps) {
    std::string app_process32 = "/system/bin/app_process32";
    std::string app_process64 = "/system/bin/app_process64";
    std::string other_binary = "/system/bin/foo";

    std::string package = "com.foo";
    std::string package_non_allowlisted = "com.foo2";

    std::vector<std::string> allowlist = {"com.foo"};

    // Allowlist for vendor/data partiion is not present on Android S.
    // Before S, checks below will fail. On S and later they will succeed.
    bool disableProductAllowlist = android_get_device_api_level() >= __ANDROID_API_S__;

    auto test_app_process = [&](const std::string& binary) {
        // /data app
        EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                         .appPackageName = package,
                                                         .appIsSystemApp = false,
                                                         .appIsOnVendorImage = false,
                                                         .appIsOnProductImage = false},
                                                        /* useOnProductImageEnabled = */ false,
                                                        allowlist));

        // /system app
        EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                          .appPackageName = package,
                                                          .appIsSystemApp = true,
                                                          .appIsOnVendorImage = false,
                                                          .appIsOnProductImage = false},
                                                         /* useOnProductImageEnabled = */ false,
                                                         allowlist));

        // /vendor || /odm app
        EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                         .appPackageName = package,
                                                         .appIsSystemApp = true,
                                                         .appIsOnVendorImage = true,
                                                         .appIsOnProductImage = false},
                                                        /* useOnProductImageEnabled = */ false,
                                                        allowlist));

        // /product app, disabled
        EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                          .appPackageName = package,
                                                          .appIsSystemApp = true,
                                                          .appIsOnVendorImage = false,
                                                          .appIsOnProductImage = true},
                                                         /* useOnProductImageEnabled = */ false,
                                                         allowlist));

        // /product app, enabled
        EXPECT_TRUE(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                         .appPackageName = package,
                                                         .appIsSystemApp = true,
                                                         .appIsOnVendorImage = false,
                                                         .appIsOnProductImage = true},
                                                        /* useOnProductImageEnabled = */ true,
                                                        allowlist));

        // /product app, enabled, package name not on allowlist
        EXPECT_EQ(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                       .appPackageName = package_non_allowlisted,
                                                       .appIsSystemApp = true,
                                                       .appIsOnVendorImage = false,
                                                       .appIsOnProductImage = true},
                                                      /* useOnProductImageEnabled = */ true,
                                                      allowlist),
                  disableProductAllowlist);

        // /data app, package name not on allowlist
        EXPECT_EQ(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                       .appPackageName = package_non_allowlisted,
                                                       .appIsSystemApp = false,
                                                       .appIsOnVendorImage = false,
                                                       .appIsOnProductImage = false},
                                                      /* useOnProductImageEnabled = */ false,
                                                      allowlist),
                  disableProductAllowlist);

        // /vendor || /odm app, package name not on allowlist
        EXPECT_EQ(TypeManager::isExtensionsUseAllowed({.binaryPath = binary,
                                                       .appPackageName = package_non_allowlisted,
                                                       .appIsSystemApp = true,
                                                       .appIsOnVendorImage = true,
                                                       .appIsOnProductImage = false},
                                                      /* useOnProductImageEnabled = */ false,
                                                      allowlist),
                  disableProductAllowlist);
    };
    test_app_process(app_process64);
    test_app_process(app_process32);

    // Test all positive cases fail if binary is not app_process32|64
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
                                                      .appPackageName = package,
                                                      .appIsSystemApp = false,
                                                      .appIsOnVendorImage = false,
                                                      .appIsOnProductImage = false},
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));
    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
                                                      .appPackageName = package,
                                                      .appIsSystemApp = true,
                                                      .appIsOnVendorImage = true,
                                                      .appIsOnProductImage = false},
                                                     /* useOnProductImageEnabled = */ false,
                                                     allowlist));

    EXPECT_FALSE(TypeManager::isExtensionsUseAllowed({.binaryPath = other_binary,
                                                      .appPackageName = package,
                                                      .appIsSystemApp = true,
                                                      .appIsOnVendorImage = false,
                                                      .appIsOnProductImage = true},
                                                     /* useOnProductImageEnabled = */ true,
                                                     allowlist));
}

}  // namespace
