Просмотр исходного кода

Merge pull request #2166 from lioncash/vi-init-service

service/vi: Unstub GetDisplayService
bunnei 7 лет назад
Родитель
Сommit
e8a21f5276

+ 15 - 0
src/core/hle/ipc_helpers.h

@@ -362,6 +362,11 @@ inline u32 RequestParser::Pop() {
     return cmdbuf[index++];
     return cmdbuf[index++];
 }
 }
 
 
+template <>
+inline s32 RequestParser::Pop() {
+    return static_cast<s32>(Pop<u32>());
+}
+
 template <typename T>
 template <typename T>
 void RequestParser::PopRaw(T& value) {
 void RequestParser::PopRaw(T& value) {
     std::memcpy(&value, cmdbuf + index, sizeof(T));
     std::memcpy(&value, cmdbuf + index, sizeof(T));
@@ -392,6 +397,16 @@ inline u64 RequestParser::Pop() {
     return msw << 32 | lsw;
     return msw << 32 | lsw;
 }
 }
 
 
+template <>
+inline s8 RequestParser::Pop() {
+    return static_cast<s8>(Pop<u8>());
+}
+
+template <>
+inline s16 RequestParser::Pop() {
+    return static_cast<s16>(Pop<u16>());
+}
+
 template <>
 template <>
 inline s64 RequestParser::Pop() {
 inline s64 RequestParser::Pop() {
     return static_cast<s64>(Pop<u64>());
     return static_cast<s64>(Pop<u64>());

+ 27 - 11
src/core/hle/service/vi/vi.cpp

@@ -24,6 +24,7 @@
 #include "core/hle/service/nvdrv/nvdrv.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
 #include "core/hle/service/nvflinger/nvflinger.h"
 #include "core/hle/service/nvflinger/nvflinger.h"
+#include "core/hle/service/service.h"
 #include "core/hle/service/vi/vi.h"
 #include "core/hle/service/vi/vi.h"
 #include "core/hle/service/vi/vi_m.h"
 #include "core/hle/service/vi/vi_m.h"
 #include "core/hle/service/vi/vi_s.h"
 #include "core/hle/service/vi/vi_s.h"
@@ -33,6 +34,7 @@
 namespace Service::VI {
 namespace Service::VI {
 
 
 constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1};
 constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1};
+constexpr ResultCode ERR_PERMISSION_DENIED{ErrorModule::VI, 5};
 constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6};
 constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6};
 constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7};
 constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7};
 
 
@@ -1203,26 +1205,40 @@ IApplicationDisplayService::IApplicationDisplayService(
     RegisterHandlers(functions);
     RegisterHandlers(functions);
 }
 }
 
 
-Module::Interface::Interface(std::shared_ptr<Module> module, const char* name,
-                             std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
-    : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {}
+static bool IsValidServiceAccess(Permission permission, Policy policy) {
+    if (permission == Permission::User) {
+        return policy == Policy::User;
+    }
+
+    if (permission == Permission::System || permission == Permission::Manager) {
+        return policy == Policy::User || policy == Policy::Compositor;
+    }
 
 
-Module::Interface::~Interface() = default;
+    return false;
+}
 
 
-void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) {
-    LOG_WARNING(Service_VI, "(STUBBED) called");
+void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx,
+                                   std::shared_ptr<NVFlinger::NVFlinger> nv_flinger,
+                                   Permission permission) {
+    IPC::RequestParser rp{ctx};
+    const auto policy = rp.PopEnum<Policy>();
+
+    if (!IsValidServiceAccess(permission, policy)) {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(ERR_PERMISSION_DENIED);
+        return;
+    }
 
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);
+    rb.PushIpcInterface<IApplicationDisplayService>(std::move(nv_flinger));
 }
 }
 
 
 void InstallInterfaces(SM::ServiceManager& service_manager,
 void InstallInterfaces(SM::ServiceManager& service_manager,
                        std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) {
                        std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) {
-    auto module = std::make_shared<Module>();
-    std::make_shared<VI_M>(module, nv_flinger)->InstallAsService(service_manager);
-    std::make_shared<VI_S>(module, nv_flinger)->InstallAsService(service_manager);
-    std::make_shared<VI_U>(module, nv_flinger)->InstallAsService(service_manager);
+    std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager);
+    std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager);
+    std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager);
 }
 }
 
 
 } // namespace Service::VI
 } // namespace Service::VI

+ 26 - 14
src/core/hle/service/vi/vi.h

@@ -4,12 +4,21 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "core/hle/service/service.h"
+#include <memory>
+#include "common/common_types.h"
+
+namespace Kernel {
+class HLERequestContext;
+}
 
 
 namespace Service::NVFlinger {
 namespace Service::NVFlinger {
 class NVFlinger;
 class NVFlinger;
 }
 }
 
 
+namespace Service::SM {
+class ServiceManager;
+}
+
 namespace Service::VI {
 namespace Service::VI {
 
 
 enum class DisplayResolution : u32 {
 enum class DisplayResolution : u32 {
@@ -19,22 +28,25 @@ enum class DisplayResolution : u32 {
     UndockedHeight = 720,
     UndockedHeight = 720,
 };
 };
 
 
-class Module final {
-public:
-    class Interface : public ServiceFramework<Interface> {
-    public:
-        explicit Interface(std::shared_ptr<Module> module, const char* name,
-                           std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
-        ~Interface() override;
-
-        void GetDisplayService(Kernel::HLERequestContext& ctx);
+/// Permission level for a particular VI service instance
+enum class Permission {
+    User,
+    System,
+    Manager,
+};
 
 
-    protected:
-        std::shared_ptr<Module> module;
-        std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;
-    };
+/// A policy type that may be requested via GetDisplayService and
+/// GetDisplayServiceWithProxyNameExchange
+enum class Policy {
+    User,
+    Compositor,
 };
 };
 
 
+namespace detail {
+void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx,
+                           std::shared_ptr<NVFlinger::NVFlinger> nv_flinger, Permission permission);
+} // namespace detail
+
 /// Registers all VI services with the specified service manager.
 /// Registers all VI services with the specified service manager.
 void InstallInterfaces(SM::ServiceManager& service_manager,
 void InstallInterfaces(SM::ServiceManager& service_manager,
                        std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
                        std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);

+ 10 - 2
src/core/hle/service/vi/vi_m.cpp

@@ -2,12 +2,14 @@
 // Licensed under GPLv2 or any later version
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 // Refer to the license.txt file included.
 
 
+#include "common/logging/log.h"
+#include "core/hle/service/vi/vi.h"
 #include "core/hle/service/vi/vi_m.h"
 #include "core/hle/service/vi/vi_m.h"
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-VI_M::VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
-    : Module::Interface(std::move(module), "vi:m", std::move(nv_flinger)) {
+VI_M::VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
+    : ServiceFramework{"vi:m"}, nv_flinger{std::move(nv_flinger)} {
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {2, &VI_M::GetDisplayService, "GetDisplayService"},
         {2, &VI_M::GetDisplayService, "GetDisplayService"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -17,4 +19,10 @@ VI_M::VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger>
 
 
 VI_M::~VI_M() = default;
 VI_M::~VI_M() = default;
 
 
+void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_VI, "called");
+
+    detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::Manager);
+}
+
 } // namespace Service::VI
 } // namespace Service::VI

+ 16 - 3
src/core/hle/service/vi/vi_m.h

@@ -4,14 +4,27 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "core/hle/service/vi/vi.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class HLERequestContext;
+}
+
+namespace Service::NVFlinger {
+class NVFlinger;
+}
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-class VI_M final : public Module::Interface {
+class VI_M final : public ServiceFramework<VI_M> {
 public:
 public:
-    explicit VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
+    explicit VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
     ~VI_M() override;
     ~VI_M() override;
+
+private:
+    void GetDisplayService(Kernel::HLERequestContext& ctx);
+
+    std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;
 };
 };
 
 
 } // namespace Service::VI
 } // namespace Service::VI

+ 10 - 2
src/core/hle/service/vi/vi_s.cpp

@@ -2,12 +2,14 @@
 // Licensed under GPLv2 or any later version
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 // Refer to the license.txt file included.
 
 
+#include "common/logging/log.h"
+#include "core/hle/service/vi/vi.h"
 #include "core/hle/service/vi/vi_s.h"
 #include "core/hle/service/vi/vi_s.h"
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-VI_S::VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
-    : Module::Interface(std::move(module), "vi:s", std::move(nv_flinger)) {
+VI_S::VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
+    : ServiceFramework{"vi:s"}, nv_flinger{std::move(nv_flinger)} {
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {1, &VI_S::GetDisplayService, "GetDisplayService"},
         {1, &VI_S::GetDisplayService, "GetDisplayService"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -17,4 +19,10 @@ VI_S::VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger>
 
 
 VI_S::~VI_S() = default;
 VI_S::~VI_S() = default;
 
 
+void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_VI, "called");
+
+    detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::System);
+}
+
 } // namespace Service::VI
 } // namespace Service::VI

+ 16 - 3
src/core/hle/service/vi/vi_s.h

@@ -4,14 +4,27 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "core/hle/service/vi/vi.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class HLERequestContext;
+}
+
+namespace Service::NVFlinger {
+class NVFlinger;
+}
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-class VI_S final : public Module::Interface {
+class VI_S final : public ServiceFramework<VI_S> {
 public:
 public:
-    explicit VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
+    explicit VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
     ~VI_S() override;
     ~VI_S() override;
+
+private:
+    void GetDisplayService(Kernel::HLERequestContext& ctx);
+
+    std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;
 };
 };
 
 
 } // namespace Service::VI
 } // namespace Service::VI

+ 10 - 2
src/core/hle/service/vi/vi_u.cpp

@@ -2,12 +2,14 @@
 // Licensed under GPLv2 or any later version
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 // Refer to the license.txt file included.
 
 
+#include "common/logging/log.h"
+#include "core/hle/service/vi/vi.h"
 #include "core/hle/service/vi/vi_u.h"
 #include "core/hle/service/vi/vi_u.h"
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-VI_U::VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
-    : Module::Interface(std::move(module), "vi:u", std::move(nv_flinger)) {
+VI_U::VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
+    : ServiceFramework{"vi:u"}, nv_flinger{std::move(nv_flinger)} {
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, &VI_U::GetDisplayService, "GetDisplayService"},
         {0, &VI_U::GetDisplayService, "GetDisplayService"},
     };
     };
@@ -16,4 +18,10 @@ VI_U::VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger>
 
 
 VI_U::~VI_U() = default;
 VI_U::~VI_U() = default;
 
 
+void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_VI, "called");
+
+    detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::User);
+}
+
 } // namespace Service::VI
 } // namespace Service::VI

+ 16 - 3
src/core/hle/service/vi/vi_u.h

@@ -4,14 +4,27 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "core/hle/service/vi/vi.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class HLERequestContext;
+}
+
+namespace Service::NVFlinger {
+class NVFlinger;
+}
 
 
 namespace Service::VI {
 namespace Service::VI {
 
 
-class VI_U final : public Module::Interface {
+class VI_U final : public ServiceFramework<VI_U> {
 public:
 public:
-    explicit VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
+    explicit VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
     ~VI_U() override;
     ~VI_U() override;
+
+private:
+    void GetDisplayService(Kernel::HLERequestContext& ctx);
+
+    std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;
 };
 };
 
 
 } // namespace Service::VI
 } // namespace Service::VI