Compare commits

..

1 Commits

Author SHA1 Message Date
t895
ca786df823 android: Fix overlay visibility reset
Flipped this bool somehow -_-
2024-02-19 13:32:01 -05:00
76 changed files with 1276 additions and 2115 deletions

View File

@@ -64,17 +64,17 @@ data class PlayerInput(
fun hasMapping(): Boolean {
var hasMapping = false
buttons.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
if (it != "[empty]") {
hasMapping = true
}
}
analogs.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
if (it != "[empty]") {
hasMapping = true
}
}
motions.forEach {
if (it != "[empty]" && it.isNotEmpty()) {
if (it != "[empty]") {
hasMapping = true
}
}

View File

@@ -6,8 +6,7 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig
enum class StringSetting(override val key: String) : AbstractStringSetting {
DRIVER_PATH("driver_path"),
DEVICE_NAME("device_name");
DRIVER_PATH("driver_path");
override fun getString(needsGlobal: Boolean): String = NativeConfig.getString(key, needsGlobal)

View File

@@ -16,7 +16,6 @@ import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.utils.NativeConfig
/**
@@ -76,9 +75,6 @@ abstract class SettingsItem(
get() = NativeLibrary.isRunning() && !setting.global &&
!NativeConfig.isPerGameConfigLoaded()
val clearable: Boolean
get() = !setting.global && NativeConfig.isPerGameConfigLoaded()
companion object {
const val TYPE_HEADER = 0
const val TYPE_SWITCH = 1
@@ -91,7 +87,6 @@ abstract class SettingsItem(
const val TYPE_INPUT = 8
const val TYPE_INT_SINGLE_CHOICE = 9
const val TYPE_INPUT_PROFILE = 10
const val TYPE_STRING_INPUT = 11
const val FASTMEM_COMBINED = "fastmem_combined"
@@ -110,7 +105,6 @@ abstract class SettingsItem(
// List of all general
val settingsItems = HashMap<String, SettingsItem>().apply {
put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name))
put(
SwitchSetting(
BooleanSetting.RENDERER_USE_SPEED_LIMIT,

View File

@@ -1,22 +0,0 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting
class StringInputSetting(
setting: AbstractStringSetting,
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = ""
) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_STRING_INPUT
fun getSelectedValue(needsGlobal: Boolean = false) = setting.getValueAsString(needsGlobal)
fun setSelectedValue(selection: String) =
(setting as AbstractStringSetting).setString(selection)
}

View File

@@ -85,10 +85,6 @@ class SettingsAdapter(
InputProfileViewHolder(ListItemSettingBinding.inflate(inflater), this)
}
SettingsItem.TYPE_STRING_INPUT -> {
StringInputViewHolder(ListItemSettingBinding.inflate(inflater), this)
}
else -> {
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
}
@@ -396,15 +392,6 @@ class SettingsAdapter(
popup.show()
}
fun onStringInputClick(item: StringInputSetting, position: Int) {
SettingsDialogFragment.newInstance(
settingsViewModel,
item,
SettingsItem.TYPE_STRING_INPUT,
position
).show(fragment.childFragmentManager, SettingsDialogFragment.TAG)
}
fun onLongClick(item: SettingsItem, position: Int): Boolean {
SettingsDialogFragment.newInstance(
settingsViewModel,

View File

@@ -14,7 +14,6 @@ import androidx.fragment.app.activityViewModels
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.slider.Slider
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.DialogEditTextBinding
import org.yuzu.yuzu_emu.databinding.DialogSliderBinding
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.features.input.model.AnalogDirection
@@ -24,7 +23,6 @@ import org.yuzu.yuzu_emu.features.settings.model.view.IntSingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting
import org.yuzu.yuzu_emu.features.settings.model.view.StringInputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting
import org.yuzu.yuzu_emu.utils.ParamPackage
import org.yuzu.yuzu_emu.utils.collect
@@ -39,7 +37,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
private val settingsViewModel: SettingsViewModel by activityViewModels()
private lateinit var sliderBinding: DialogSliderBinding
private lateinit var stringInputBinding: DialogEditTextBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -134,18 +131,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
.create()
}
SettingsItem.TYPE_STRING_INPUT -> {
stringInputBinding = DialogEditTextBinding.inflate(layoutInflater)
val item = settingsViewModel.clickedItem as StringInputSetting
stringInputBinding.editText.setText(item.getSelectedValue())
MaterialAlertDialogBuilder(requireContext())
.setTitle(item.title)
.setView(stringInputBinding.root)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, defaultCancelListener)
.create()
}
SettingsItem.TYPE_STRING_SINGLE_CHOICE -> {
val item = settingsViewModel.clickedItem as StringSingleChoiceSetting
MaterialAlertDialogBuilder(requireContext())
@@ -173,7 +158,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
): View? {
return when (type) {
SettingsItem.TYPE_SLIDER -> sliderBinding.root
SettingsItem.TYPE_STRING_INPUT -> stringInputBinding.root
else -> super.onCreateView(inflater, container, savedInstanceState)
}
}
@@ -216,13 +200,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
val sliderSetting = settingsViewModel.clickedItem as SliderSetting
sliderSetting.setSelectedValue(settingsViewModel.sliderProgress.value)
}
is StringInputSetting -> {
val stringInputSetting = settingsViewModel.clickedItem as StringInputSetting
stringInputSetting.setSelectedValue(
(stringInputBinding.editText.text ?: "").toString()
)
}
}
closeDialog()
}

View File

@@ -23,7 +23,6 @@ import org.yuzu.yuzu_emu.features.settings.model.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.model.Settings.MenuTag
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.features.settings.model.view.*
import org.yuzu.yuzu_emu.utils.InputHandler
import org.yuzu.yuzu_emu.utils.NativeConfig
@@ -154,7 +153,6 @@ class SettingsFragmentPresenter(
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(StringSetting.DEVICE_NAME.key)
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
add(BooleanSetting.USE_DOCKED_MODE.key)
@@ -780,7 +778,7 @@ class SettingsFragmentPresenter(
playerIndex: Int,
paramName: String,
stick: NativeAnalog,
defaultValue: Float
defaultValue: Int
): AbstractIntSetting =
object : AbstractIntSetting {
val params get() = NativeInput.getStickParam(playerIndex, stick)
@@ -788,7 +786,7 @@ class SettingsFragmentPresenter(
override val key = ""
override fun getInt(needsGlobal: Boolean): Int =
(params.get(paramName, defaultValue) * 100).toInt()
(params.get(paramName, 0.15f) * 100).toInt()
override fun setInt(value: Int) {
val tempParams = params
@@ -796,12 +794,12 @@ class SettingsFragmentPresenter(
NativeInput.setStickParam(playerIndex, stick, tempParams)
}
override val defaultValue = (defaultValue * 100).toInt()
override val defaultValue = defaultValue
override fun getValueAsString(needsGlobal: Boolean): String =
getInt(needsGlobal).toString()
override fun reset() = setInt(this.defaultValue)
override fun reset() = setInt(defaultValue)
}
private fun getExtraStickSettings(
@@ -811,11 +809,11 @@ class SettingsFragmentPresenter(
val stickIsController =
NativeInput.isController(NativeInput.getStickParam(playerIndex, nativeAnalog))
val modifierRangeSetting =
getStickIntSettingFromParam(playerIndex, "modifier_scale", nativeAnalog, 0.5f)
getStickIntSettingFromParam(playerIndex, "modifier_scale", nativeAnalog, 50)
val stickRangeSetting =
getStickIntSettingFromParam(playerIndex, "range", nativeAnalog, 0.95f)
getStickIntSettingFromParam(playerIndex, "range", nativeAnalog, 95)
val stickDeadzoneSetting =
getStickIntSettingFromParam(playerIndex, "deadzone", nativeAnalog, 0.15f)
getStickIntSettingFromParam(playerIndex, "deadzone", nativeAnalog, 15)
val out = mutableListOf<SettingsItem>().apply {
if (stickIsController) {

View File

@@ -13,6 +13,7 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
@@ -31,7 +32,9 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
binding.textSettingValue.text = dateFormatter.format(zonedTime)
binding.buttonClear.setVisible(setting.clearable)
binding.buttonClear.setVisible(
!setting.setting.global || NativeConfig.isPerGameConfigLoaded()
)
binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition)
}

View File

@@ -10,6 +10,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
@@ -47,7 +48,9 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
binding.textSettingValue.setVisible(false)
}
binding.buttonClear.setVisible(setting.clearable)
binding.buttonClear.setVisible(
!setting.setting.global || NativeConfig.isPerGameConfigLoaded()
)
binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition)
}

View File

@@ -9,6 +9,7 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
@@ -27,7 +28,9 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
setting.units
)
binding.buttonClear.setVisible(setting.clearable)
binding.buttonClear.setVisible(
!setting.setting.global || NativeConfig.isPerGameConfigLoaded()
)
binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition)
}

View File

@@ -1,45 +0,0 @@
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.StringInputSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class StringInputViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) {
private lateinit var setting: StringInputSetting
override fun bind(item: SettingsItem) {
setting = item as StringInputSetting
binding.textSettingName.text = setting.title
binding.textSettingDescription.setVisible(setting.description.isNotEmpty())
binding.textSettingDescription.text = setting.description
binding.textSettingValue.setVisible(true)
binding.textSettingValue.text = setting.getSelectedValue()
binding.buttonClear.setVisible(setting.clearable)
binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition)
}
setStyle(setting.isEditable, binding)
}
override fun onClick(clicked: View) {
if (setting.isEditable) {
adapter.onStringInputClick(setting, bindingAdapterPosition)
}
}
override fun onLongClick(clicked: View): Boolean {
if (setting.isEditable) {
return adapter.onLongClick(setting, bindingAdapterPosition)
}
return false
}
}

View File

@@ -9,6 +9,7 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) :
@@ -28,7 +29,9 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
adapter.onBooleanClick(setting, binding.switchWidget.isChecked, bindingAdapterPosition)
}
binding.buttonClear.setVisible(setting.clearable)
binding.buttonClear.setVisible(
!setting.setting.global || NativeConfig.isPerGameConfigLoaded()
)
binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition)
}

View File

@@ -810,7 +810,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
}
binding.doneControlConfig.setVisible(true)
binding.doneControlConfig.setVisible(false)
binding.surfaceInputOverlay.setIsInEditMode(true)
}

View File

@@ -28,7 +28,6 @@ import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
import org.yuzu.yuzu_emu.features.input.model.NativeButton
import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.overlay.model.OverlayControl
@@ -100,10 +99,12 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
}
var shouldUpdateView = false
val playerIndex = when (NativeInput.getStyleIndex(0)) {
NpadStyleIndex.Handheld -> 8
else -> 0
}
val playerIndex =
if (NativeInput.isHandheldOnly()) {
NativeInput.ConsoleDevice
} else {
NativeInput.Player1Device
}
for (button in overlayButtons) {
if (!button.updateStatus(event)) {

View File

@@ -292,9 +292,6 @@ void EmulationSession::ShutdownEmulation() {
// Unload user input.
m_system.HIDCore().UnloadInputDevices();
// Enable all controllers
m_system.HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
// Shutdown the main emulated process
if (m_load_result == Core::SystemResultStatus::Success) {
m_system.DetachDebugger();

View File

@@ -102,50 +102,8 @@ void ApplyControllerConfig(size_t player_index,
}
}
std::vector<s32> GetSupportedStyles(int player_index) {
auto& hid_core = EmulationSession::GetInstance().System().HIDCore();
const auto npad_style_set = hid_core.GetSupportedStyleTag();
std::vector<s32> supported_indexes;
if (npad_style_set.fullkey == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::Fullkey));
}
if (npad_style_set.joycon_dual == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconDual));
}
if (npad_style_set.joycon_left == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconLeft));
}
if (npad_style_set.joycon_right == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconRight));
}
if (player_index == 0 && npad_style_set.handheld == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::Handheld));
}
if (npad_style_set.gamecube == 1) {
supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::GameCube));
}
return supported_indexes;
}
void ConnectController(size_t player_index, bool connected) {
auto& hid_core = EmulationSession::GetInstance().System().HIDCore();
ApplyControllerConfig(player_index, [&](Core::HID::EmulatedController* controller) {
auto supported_styles = GetSupportedStyles(player_index);
auto controller_style = controller->GetNpadStyleIndex(true);
auto style = std::find(supported_styles.begin(), supported_styles.end(),
static_cast<int>(controller_style));
if (style == supported_styles.end() && !supported_styles.empty()) {
controller->SetNpadStyleIndex(
static_cast<Core::HID::NpadStyleIndex>(supported_styles[0]));
}
});
if (player_index == 0) {
auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
auto* player_one = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
@@ -564,10 +522,36 @@ jint Java_org_yuzu_yuzu_1emu_features_input_NativeInput_getButtonNameImpl(JNIEnv
jintArray Java_org_yuzu_yuzu_1emu_features_input_NativeInput_getSupportedStyleTagsImpl(
JNIEnv* env, jobject j_obj, jint j_player_index) {
auto supported_styles = GetSupportedStyles(j_player_index);
jintArray j_supported_indexes = env->NewIntArray(supported_styles.size());
env->SetIntArrayRegion(j_supported_indexes, 0, supported_styles.size(),
supported_styles.data());
auto& hid_core = EmulationSession::GetInstance().System().HIDCore();
const auto npad_style_set = hid_core.GetSupportedStyleTag();
std::vector<s32> supported_indexes;
if (npad_style_set.fullkey == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::Fullkey));
}
if (npad_style_set.joycon_dual == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconDual));
}
if (npad_style_set.joycon_left == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconLeft));
}
if (npad_style_set.joycon_right == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconRight));
}
if (j_player_index == 0 && npad_style_set.handheld == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::Handheld));
}
if (npad_style_set.gamecube == 1) {
supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::GameCube));
}
jintArray j_supported_indexes = env->NewIntArray(supported_indexes.size());
env->SetIntArrayRegion(j_supported_indexes, 0, supported_indexes.size(),
supported_indexes.data());
return j_supported_indexes;
}

View File

@@ -209,7 +209,6 @@
<string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
<string name="device_name">Device name</string>
<string name="use_docked_mode">Docked Mode</string>
<string name="use_docked_mode_description">Increases resolution, decreasing performance. Handheld Mode is used when disabled, lowering resolution and increasing performance.</string>
<string name="emulated_region">Emulated region</string>

View File

@@ -543,16 +543,6 @@ add_library(core STATIC
hle/service/btdrv/btdrv.h
hle/service/btm/btm.cpp
hle/service/btm/btm.h
hle/service/btm/btm_debug.cpp
hle/service/btm/btm_debug.h
hle/service/btm/btm_system.cpp
hle/service/btm/btm_system.h
hle/service/btm/btm_system_core.cpp
hle/service/btm/btm_system_core.h
hle/service/btm/btm_user.cpp
hle/service/btm/btm_user.h
hle/service/btm/btm_user_core.cpp
hle/service/btm/btm_user_core.h
hle/service/caps/caps.cpp
hle/service/caps/caps.h
hle/service/caps/caps_a.cpp
@@ -860,20 +850,8 @@ add_library(core STATIC
hle/service/nvnflinger/ui/graphic_buffer.cpp
hle/service/nvnflinger/ui/graphic_buffer.h
hle/service/nvnflinger/window.h
hle/service/olsc/daemon_controller.cpp
hle/service/olsc/daemon_controller.h
hle/service/olsc/native_handle_holder.cpp
hle/service/olsc/native_handle_holder.h
hle/service/olsc/olsc_service_for_application.cpp
hle/service/olsc/olsc_service_for_application.h
hle/service/olsc/olsc_service_for_system_service.cpp
hle/service/olsc/olsc_service_for_system_service.h
hle/service/olsc/olsc.cpp
hle/service/olsc/olsc.h
hle/service/olsc/remote_storage_controller.cpp
hle/service/olsc/remote_storage_controller.h
hle/service/olsc/transfer_task_list_controller.cpp
hle/service/olsc/transfer_task_list_controller.h
hle/service/omm/omm.cpp
hle/service/omm/omm.h
hle/service/omm/operation_mode_manager.cpp
@@ -893,14 +871,10 @@ add_library(core STATIC
hle/service/os/mutex.h
hle/service/pcie/pcie.cpp
hle/service/pcie/pcie.h
hle/service/pctl/parental_control_service_factory.cpp
hle/service/pctl/parental_control_service_factory.h
hle/service/pctl/parental_control_service.cpp
hle/service/pctl/parental_control_service.h
hle/service/pctl/pctl.cpp
hle/service/pctl/pctl.h
hle/service/pctl/pctl_results.h
hle/service/pctl/pctl_types.h
hle/service/pctl/pctl_module.cpp
hle/service/pctl/pctl_module.h
hle/service/pcv/pcv.cpp
hle/service/pcv/pcv.h
hle/service/pm/pm.cpp

View File

@@ -3,7 +3,6 @@
#pragma once
#include <mutex>
#include <optional>
#include "core/crypto/aes_util.h"

View File

@@ -3,18 +3,141 @@
#include <memory>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/btm/btm.h"
#include "core/hle/service/btm/btm_debug.h"
#include "core/hle/service/btm/btm_system.h"
#include "core/hle/service/btm/btm_user.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
namespace Service::BTM {
class IBtm final : public ServiceFramework<IBtm> {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
public:
explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} {
explicit IBtmUserCore(Core::System& system_)
: ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
{1, nullptr, "GetBleScanFilterParameter"},
{2, nullptr, "GetBleScanFilterParameter2"},
{3, nullptr, "StartBleScanForGeneral"},
{4, nullptr, "StopBleScanForGeneral"},
{5, nullptr, "GetBleScanResultsForGeneral"},
{6, nullptr, "StartBleScanForPaired"},
{7, nullptr, "StopBleScanForPaired"},
{8, nullptr, "StartBleScanForSmartDevice"},
{9, nullptr, "StopBleScanForSmartDevice"},
{10, nullptr, "GetBleScanResultsForSmartDevice"},
{17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"},
{18, nullptr, "BleConnect"},
{19, nullptr, "BleDisconnect"},
{20, nullptr, "BleGetConnectionState"},
{21, nullptr, "AcquireBlePairingEvent"},
{22, nullptr, "BlePairDevice"},
{23, nullptr, "BleUnPairDevice"},
{24, nullptr, "BleUnPairDevice2"},
{25, nullptr, "BleGetPairedDevices"},
{26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"},
{27, nullptr, "GetGattServices"},
{28, nullptr, "GetGattService"},
{29, nullptr, "GetGattIncludedServices"},
{30, nullptr, "GetBelongingGattService"},
{31, nullptr, "GetGattCharacteristics"},
{32, nullptr, "GetGattDescriptors"},
{33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"},
{34, nullptr, "ConfigureBleMtu"},
{35, nullptr, "GetBleMtu"},
{36, nullptr, "RegisterBleGattDataPath"},
{37, nullptr, "UnregisterBleGattDataPath"},
};
// clang-format on
RegisterHandlers(functions);
scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent");
connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent");
service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent");
config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent");
}
~IBtmUserCore() override {
service_context.CloseEvent(scan_event);
service_context.CloseEvent(connection_event);
service_context.CloseEvent(service_discovery_event);
service_context.CloseEvent(config_event);
}
private:
void AcquireBleScanEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(scan_event->GetReadableEvent());
}
void AcquireBleConnectionEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(connection_event->GetReadableEvent());
}
void AcquireBleServiceDiscoveryEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(service_discovery_event->GetReadableEvent());
}
void AcquireBleMtuConfigEvent(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
rb.Push(true);
rb.PushCopyObjects(config_event->GetReadableEvent());
}
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* scan_event;
Kernel::KEvent* connection_event;
Kernel::KEvent* service_discovery_event;
Kernel::KEvent* config_event;
};
class BTM_USR final : public ServiceFramework<BTM_USR> {
public:
explicit BTM_USR(Core::System& system_) : ServiceFramework{system_, "btm:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BTM_USR::GetCore, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IBtmUserCore>(system);
}
};
class BTM final : public ServiceFramework<BTM> {
public:
explicit BTM(Core::System& system_) : ServiceFramework{system_, "btm"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetState"},
@@ -109,13 +232,144 @@ public:
}
};
class BTM_DBG final : public ServiceFramework<BTM_DBG> {
public:
explicit BTM_DBG(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AcquireDiscoveryEvent"},
{1, nullptr, "StartDiscovery"},
{2, nullptr, "CancelDiscovery"},
{3, nullptr, "GetDeviceProperty"},
{4, nullptr, "CreateBond"},
{5, nullptr, "CancelBond"},
{6, nullptr, "SetTsiMode"},
{7, nullptr, "GeneralTest"},
{8, nullptr, "HidConnect"},
{9, nullptr, "GeneralGet"},
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
public:
explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
{1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, nullptr, "EnableRadio"},
{5, nullptr, "DisableRadio"},
{6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
{7, nullptr, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
{10, nullptr, "StartAudioDeviceDiscovery"},
{11, nullptr, "StopAudioDeviceDiscovery"},
{12, nullptr, "IsDiscoveryingAudioDevice"},
{13, nullptr, "GetDiscoveredAudioDevice"},
{14, nullptr, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
{17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, &IBtmSystemCore::GetPairedAudioDevices, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
{22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
{23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
}
private:
void IsRadioEnabled(HLERequestContext& ctx) {
LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(true);
}
void StartGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelGamepadPairing(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetConnectedAudioDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void GetPairedAudioDevices(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
};
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
public:
explicit BTM_SYS(Core::System& system_) : ServiceFramework{system_, "btm:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BTM_SYS::GetCore, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetCore(HLERequestContext& ctx) {
LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IBtmSystemCore>(system);
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("btm", std::make_shared<IBtm>(system));
server_manager->RegisterNamedService("btm:dbg", std::make_shared<IBtmDebug>(system));
server_manager->RegisterNamedService("btm:sys", std::make_shared<IBtmSystem>(system));
server_manager->RegisterNamedService("btm:u", std::make_shared<IBtmUser>(system));
server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system));
server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system));
server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system));
server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system));
ServerManager::RunServer(std::move(server_manager));
}

View File

@@ -3,6 +3,10 @@
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Core {
class System;
};

View File

@@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/btm/btm_debug.h"
namespace Service::BTM {
IBtmDebug::IBtmDebug(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AcquireDiscoveryEvent"},
{1, nullptr, "StartDiscovery"},
{2, nullptr, "CancelDiscovery"},
{3, nullptr, "GetDeviceProperty"},
{4, nullptr, "CreateBond"},
{5, nullptr, "CancelBond"},
{6, nullptr, "SetTsiMode"},
{7, nullptr, "GeneralTest"},
{8, nullptr, "HidConnect"},
{9, nullptr, "GeneralGet"},
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmDebug::~IBtmDebug() = default;
} // namespace Service::BTM

View File

@@ -1,21 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmDebug final : public ServiceFramework<IBtmDebug> {
public:
explicit IBtmDebug(Core::System& system_);
~IBtmDebug() override;
};
} // namespace Service::BTM

View File

@@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_system.h"
#include "core/hle/service/btm/btm_system_core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/service.h"
namespace Service::BTM {
IBtmSystem::IBtmSystem(Core::System& system_) : ServiceFramework{system_, "btm:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmSystem::GetCore>, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmSystem::~IBtmSystem() = default;
Result IBtmSystem::GetCore(OutInterface<IBtmSystemCore> out_interface) {
LOG_WARNING(Service_BTM, "called");
*out_interface = std::make_shared<IBtmSystemCore>(system);
R_SUCCEED();
}
} // namespace Service::BTM

View File

@@ -1,25 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmSystemCore;
class IBtmSystem final : public ServiceFramework<IBtmSystem> {
public:
explicit IBtmSystem(Core::System& system_);
~IBtmSystem() override;
private:
Result GetCore(OutInterface<IBtmSystemCore> out_interface);
};
} // namespace Service::BTM

View File

@@ -1,127 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_system_core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/set/system_settings_server.h"
#include "core/hle/service/sm/sm.h"
namespace Service::BTM {
IBtmSystemCore::IBtmSystemCore(Core::System& system_)
: ServiceFramework{system_, "IBtmSystemCore"}, service_context{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmSystemCore::StartGamepadPairing>, "StartGamepadPairing"},
{1, C<&IBtmSystemCore::CancelGamepadPairing>, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, C<&IBtmSystemCore::EnableRadio>, "EnableRadio"},
{5, C<&IBtmSystemCore::DisableRadio>, "DisableRadio"},
{6, C<&IBtmSystemCore::IsRadioEnabled>, "IsRadioEnabled"},
{7, C<&IBtmSystemCore::AcquireRadioEvent>, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
{10, nullptr, "StartAudioDeviceDiscovery"},
{11, nullptr, "StopAudioDeviceDiscovery"},
{12, nullptr, "IsDiscoveryingAudioDevice"},
{13, nullptr, "GetDiscoveredAudioDevice"},
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
{17, C<&IBtmSystemCore::GetConnectedAudioDevices>, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, C<&IBtmSystemCore::GetPairedAudioDevices>, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
{22, C<&IBtmSystemCore::RequestAudioDeviceConnectionRejection>, "RequestAudioDeviceConnectionRejection"},
{23, C<&IBtmSystemCore::CancelAudioDeviceConnectionRejection>, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
radio_event = service_context.CreateEvent("IBtmSystemCore::RadioEvent");
audio_device_connection_event =
service_context.CreateEvent("IBtmSystemCore::AudioDeviceConnectionEvent");
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
IBtmSystemCore::~IBtmSystemCore() {
service_context.CloseEvent(radio_event);
service_context.CloseEvent(audio_device_connection_event);
}
Result IBtmSystemCore::StartGamepadPairing() {
LOG_WARNING(Service_BTM, "(STUBBED) called");
R_SUCCEED();
}
Result IBtmSystemCore::CancelGamepadPairing() {
LOG_WARNING(Service_BTM, "(STUBBED) called");
R_SUCCEED();
}
Result IBtmSystemCore::EnableRadio() {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->SetBluetoothEnableFlag(true));
}
Result IBtmSystemCore::DisableRadio() {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->SetBluetoothEnableFlag(false));
}
Result IBtmSystemCore::IsRadioEnabled(Out<bool> out_is_enabled) {
LOG_DEBUG(Service_BTM, "called");
R_RETURN(m_set_sys->GetBluetoothEnableFlag(out_is_enabled));
}
Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &radio_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_event = &audio_device_connection_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmSystemCore::GetConnectedAudioDevices(
Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBtmSystemCore::GetPairedAudioDevices(
Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_count = 0;
R_SUCCEED();
}
Result IBtmSystemCore::RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) {
LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
R_SUCCEED();
}
Result IBtmSystemCore::CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) {
LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
R_SUCCEED();
}
} // namespace Service::BTM

View File

@@ -1,60 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KEvent;
class KReadableEvent;
} // namespace Kernel
namespace Core {
class System;
}
namespace Service::Set {
class ISystemSettingsServer;
}
namespace Service::BTM {
class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
public:
explicit IBtmSystemCore(Core::System& system_);
~IBtmSystemCore() override;
private:
Result StartGamepadPairing();
Result CancelGamepadPairing();
Result EnableRadio();
Result DisableRadio();
Result IsRadioEnabled(Out<bool> out_is_enabled);
Result AcquireRadioEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetConnectedAudioDevices(
Out<s32> out_count,
OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices);
Result GetPairedAudioDevices(
Out<s32> out_count,
OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices);
Result RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid);
Result CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* radio_event;
Kernel::KEvent* audio_device_connection_event;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
};
} // namespace Service::BTM

View File

@@ -1,30 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/btm/btm_user.h"
#include "core/hle/service/btm/btm_user_core.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::BTM {
IBtmUser::IBtmUser(Core::System& system_) : ServiceFramework{system_, "btm:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmUser::GetCore>, "GetCore"},
};
// clang-format on
RegisterHandlers(functions);
}
IBtmUser::~IBtmUser() = default;
Result IBtmUser::GetCore(OutInterface<IBtmUserCore> out_interface) {
LOG_WARNING(Service_BTM, "called");
*out_interface = std::make_shared<IBtmUserCore>(system);
R_SUCCEED();
}
} // namespace Service::BTM

View File

@@ -1,25 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmUserCore;
class IBtmUser final : public ServiceFramework<IBtmUser> {
public:
explicit IBtmUser(Core::System& system_);
~IBtmUser() override;
private:
Result GetCore(OutInterface<IBtmUserCore> out_interface);
};
} // namespace Service::BTM

View File

@@ -1,103 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <memory>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/btm/btm_user_core.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::BTM {
IBtmUserCore::IBtmUserCore(Core::System& system_)
: ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IBtmUserCore::AcquireBleScanEvent>, "AcquireBleScanEvent"},
{1, nullptr, "GetBleScanFilterParameter"},
{2, nullptr, "GetBleScanFilterParameter2"},
{3, nullptr, "StartBleScanForGeneral"},
{4, nullptr, "StopBleScanForGeneral"},
{5, nullptr, "GetBleScanResultsForGeneral"},
{6, nullptr, "StartBleScanForPaired"},
{7, nullptr, "StopBleScanForPaired"},
{8, nullptr, "StartBleScanForSmartDevice"},
{9, nullptr, "StopBleScanForSmartDevice"},
{10, nullptr, "GetBleScanResultsForSmartDevice"},
{17, C<&IBtmUserCore::AcquireBleConnectionEvent>, "AcquireBleConnectionEvent"},
{18, nullptr, "BleConnect"},
{19, nullptr, "BleDisconnect"},
{20, nullptr, "BleGetConnectionState"},
{21, nullptr, "AcquireBlePairingEvent"},
{22, nullptr, "BlePairDevice"},
{23, nullptr, "BleUnPairDevice"},
{24, nullptr, "BleUnPairDevice2"},
{25, nullptr, "BleGetPairedDevices"},
{26, C<&IBtmUserCore::AcquireBleServiceDiscoveryEvent>, "AcquireBleServiceDiscoveryEvent"},
{27, nullptr, "GetGattServices"},
{28, nullptr, "GetGattService"},
{29, nullptr, "GetGattIncludedServices"},
{30, nullptr, "GetBelongingGattService"},
{31, nullptr, "GetGattCharacteristics"},
{32, nullptr, "GetGattDescriptors"},
{33, C<&IBtmUserCore::AcquireBleMtuConfigEvent>, "AcquireBleMtuConfigEvent"},
{34, nullptr, "ConfigureBleMtu"},
{35, nullptr, "GetBleMtu"},
{36, nullptr, "RegisterBleGattDataPath"},
{37, nullptr, "UnregisterBleGattDataPath"},
};
// clang-format on
RegisterHandlers(functions);
scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent");
connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent");
service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent");
config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent");
}
IBtmUserCore::~IBtmUserCore() {
service_context.CloseEvent(scan_event);
service_context.CloseEvent(connection_event);
service_context.CloseEvent(service_discovery_event);
service_context.CloseEvent(config_event);
}
Result IBtmUserCore::AcquireBleScanEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &scan_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleConnectionEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &connection_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleServiceDiscoveryEvent(
Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &service_discovery_event->GetReadableEvent();
R_SUCCEED();
}
Result IBtmUserCore::AcquireBleMtuConfigEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_BTM, "(STUBBED) called");
*out_is_valid = true;
*out_event = &config_event->GetReadableEvent();
R_SUCCEED();
}
} // namespace Service::BTM

View File

@@ -1,47 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KEvent;
class KReadableEvent;
} // namespace Kernel
namespace Core {
class System;
}
namespace Service::BTM {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
public:
explicit IBtmUserCore(Core::System& system_);
~IBtmUserCore() override;
private:
Result AcquireBleScanEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleConnectionEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleServiceDiscoveryEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireBleMtuConfigEvent(Out<bool> out_is_valid,
OutCopyHandle<Kernel::KReadableEvent> out_event);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* scan_event;
Kernel::KEvent* connection_event;
Kernel::KEvent* service_discovery_event;
Kernel::KEvent* config_event;
};
} // namespace Service::BTM

View File

@@ -436,14 +436,14 @@ Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(
Result IApplicationManagerInterface::GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
u32 flags, u64 application_id, Uid account_id) {
Common::UUID account_id, u32 flags, u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called, flags={}, application_id={:016X}, account_id={}",
flags, application_id, account_id.uuid.FormattedString());
flags, application_id, account_id.FormattedString());
if (!out_rights.empty()) {
ApplicationRightsOnClient rights{};
rights.application_id = application_id;
rights.uid = account_id.uuid;
rights.uid = account_id;
rights.flags = 0;
rights.flags2 = 0;

View File

@@ -37,7 +37,7 @@ public:
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
u32 flags, u64 application_id, Uid account_id);
Common::UUID account_id, u32 flags, u64 application_id);
Result CheckSdCardMountStatus();
Result GetSdCardMountStatusChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id);

View File

@@ -108,9 +108,4 @@ struct ContentPath {
};
static_assert(sizeof(ContentPath) == 0x10, "ContentPath has incorrect size.");
struct Uid {
alignas(8) Common::UUID uuid;
};
static_assert(sizeof(Uid) == 0x10, "Uid has incorrect size.");
} // namespace Service::NS

View File

@@ -41,7 +41,8 @@ IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_,
IQueryService::~IQueryService() = default;
Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId(
Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id) {
Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id,
u64 application_id) {
// TODO(German77): Read statistics of the game
*out_play_statistics = {
.application_id = application_id,
@@ -49,7 +50,7 @@ Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId(
};
LOG_WARNING(Service_NS, "(STUBBED) called. unknown={}. application_id={:016X}, account_id={}",
unknown, application_id, account_id.uuid.FormattedString());
unknown, application_id, account_id.FormattedString());
R_SUCCEED();
}

View File

@@ -5,7 +5,6 @@
#include "common/uuid.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
@@ -30,7 +29,8 @@ public:
private:
Result QueryPlayStatisticsByApplicationIdAndUserAccountId(
Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id);
Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id,
u64 application_id);
};
} // namespace Service::NS

View File

@@ -3,6 +3,8 @@
#pragma once
#include <list>
#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
#include "core/hle/service/nvnflinger/hwc_layer.h"
@@ -24,21 +26,7 @@ struct Layer {
};
struct LayerStack {
std::vector<std::shared_ptr<Layer>> layers;
std::shared_ptr<Layer> FindLayer(s32 consumer_id) {
for (auto& layer : layers) {
if (layer->consumer_id == consumer_id) {
return layer;
}
}
return nullptr;
}
bool HasLayers() {
return !layers.empty();
}
std::list<Layer> layers;
};
struct Display {
@@ -46,6 +34,20 @@ struct Display {
id = id_;
}
Layer* FindLayer(s32 consumer_id) {
for (auto& layer : stack.layers) {
if (layer.consumer_id == consumer_id) {
return &layer;
}
}
return nullptr;
}
bool HasLayers() {
return !stack.layers.empty();
}
u64 id;
LayerStack stack;
};

View File

@@ -55,10 +55,10 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
// Acquire all necessary framebuffers.
for (auto& layer : display.stack.layers) {
auto consumer_id = layer->consumer_id;
auto consumer_id = layer.consumer_id;
// Try to fetch the framebuffer (either new or stale).
const auto result = this->CacheFramebufferLocked(*layer, consumer_id);
const auto result = this->CacheFramebufferLocked(layer, consumer_id);
// If we failed, skip this layer.
if (result == CacheStatus::NoBufferAvailable) {
@@ -75,7 +75,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
const auto& igbp_buffer = *item.graphic_buffer;
// TODO: get proper Z-index from layer
if (layer->visible) {
if (layer.visible) {
composition_stack.emplace_back(HwcLayer{
.buffer_handle = igbp_buffer.BufferId(),
.offset = igbp_buffer.Offset(),
@@ -84,7 +84,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
.height = igbp_buffer.Height(),
.stride = igbp_buffer.Stride(),
.z_index = 0,
.blending = layer->blending,
.blending = layer.blending,
.transform = static_cast<android::BufferTransformFlags>(item.transform),
.crop_rect = item.crop,
.acquire_fence = item.fence,
@@ -134,7 +134,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
continue;
}
if (const auto layer = display.stack.FindLayer(layer_id); layer != nullptr) {
if (auto* layer = display.FindLayer(layer_id); layer != nullptr) {
// TODO: support release fence
// This is needed to prevent screen tearing
layer->buffer_item_consumer->ReleaseBuffer(framebuffer.item, android::Fence::NoFence());
@@ -153,7 +153,7 @@ void HardwareComposer::RemoveLayerLocked(Display& display, ConsumerId consumer_i
}
// Try to release the buffer item.
const auto layer = display.stack.FindLayer(consumer_id);
auto* const layer = display.FindLayer(consumer_id);
if (layer && it->second.is_acquired) {
layer->buffer_item_consumer->ReleaseBuffer(it->second.item, android::Fence::NoFence());
}

View File

@@ -36,7 +36,7 @@ void SurfaceFlinger::RemoveDisplay(u64 display_id) {
bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
u64 display_id) {
auto* const display = this->FindDisplay(display_id);
if (!display || !display->stack.HasLayers()) {
if (!display || !display->HasLayers()) {
return false;
}
@@ -46,34 +46,19 @@ bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_spe
return true;
}
void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) {
void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
auto* const display = this->FindDisplay(display_id);
auto binder = std::static_pointer_cast<android::BufferQueueConsumer>(
m_server.TryGetBinder(consumer_binder_id));
if (!binder) {
if (!display || !binder) {
return;
}
auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder));
buffer_item_consumer->Connect(false);
m_layers.layers.emplace_back(
std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id));
}
void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) {
std::erase_if(m_layers.layers,
[&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
}
void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
auto* const display = this->FindDisplay(display_id);
auto layer = this->FindLayer(consumer_binder_id);
if (!display || !layer) {
return;
}
display->stack.layers.emplace_back(std::move(layer));
display->stack.layers.emplace_back(std::move(buffer_item_consumer), consumer_binder_id);
}
void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) {
@@ -84,18 +69,18 @@ void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_bi
m_composer.RemoveLayerLocked(*display, consumer_binder_id);
std::erase_if(display->stack.layers,
[&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
[&](auto& layer) { return layer.consumer_id == consumer_binder_id; });
}
void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) {
if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
layer->visible = visible;
return;
}
}
void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) {
if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
layer->blending = blending;
return;
}
@@ -111,9 +96,9 @@ Display* SurfaceFlinger::FindDisplay(u64 display_id) {
return nullptr;
}
std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
for (auto& layer : m_layers.layers) {
if (layer->consumer_id == consumer_binder_id) {
Layer* SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
for (auto& display : m_displays) {
if (auto* layer = display.FindLayer(consumer_binder_id); layer != nullptr) {
return layer;
}
}

View File

@@ -36,9 +36,6 @@ public:
void RemoveDisplay(u64 display_id);
bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
void CreateLayer(s32 consumer_binder_id);
void DestroyLayer(s32 consumer_binder_id);
void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id);
void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id);
@@ -47,7 +44,7 @@ public:
private:
Display* FindDisplay(u64 display_id);
std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id);
Layer* FindLayer(s32 consumer_binder_id);
public:
// TODO: these don't belong here
@@ -60,7 +57,6 @@ private:
KernelHelpers::ServiceContext m_context;
std::vector<Display> m_displays;
LayerStack m_layers;
std::shared_ptr<Nvidia::Module> nvdrv;
s32 disp_fd;
HardwareComposer m_composer;

View File

@@ -1,40 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/daemon_controller.h"
namespace Service::OLSC {
IDaemonController::IDaemonController(Core::System& system_)
: ServiceFramework{system_, "IDaemonController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"},
{1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"},
{2, nullptr, "GetGlobalUploadEnabledForAccount"},
{3, nullptr, "SetGlobalUploadEnabledForAccount"},
{4, nullptr, "TouchAccount"},
{5, nullptr, "GetGlobalDownloadEnabledForAccount"},
{6, nullptr, "SetGlobalDownloadEnabledForAccount"},
{10, nullptr, "GetForbiddenSaveDataIndication"},
{11, nullptr, "GetStopperObject"},
{12, nullptr, "GetState"},
};
// clang-format on
RegisterHandlers(functions);
}
IDaemonController::~IDaemonController() = default;
Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
Common::UUID user_id,
u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
user_id.FormattedString(), application_id);
*out_is_enabled = false;
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,20 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/uuid.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class IDaemonController final : public ServiceFramework<IDaemonController> {
public:
explicit IDaemonController(Core::System& system_);
~IDaemonController() override;
private:
Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
Common::UUID user_id, u64 application_id);
};
} // namespace Service::OLSC

View File

@@ -1,28 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/native_handle_holder.h"
namespace Service::OLSC {
INativeHandleHolder::INativeHandleHolder(Core::System& system_)
: ServiceFramework{system_, "INativeHandleHolder"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
INativeHandleHolder::~INativeHandleHolder() = default;
Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_event = nullptr;
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,22 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KReadableEvent;
}
namespace Service::OLSC {
class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
public:
explicit INativeHandleHolder(Core::System& system_);
~INativeHandleHolder() override;
private:
Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
};
} // namespace Service::OLSC

View File

@@ -1,27 +1,226 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/olsc/olsc.h"
#include "core/hle/service/olsc/olsc_service_for_application.h"
#include "core/hle/service/olsc/olsc_service_for_system_service.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
public:
explicit IOlscServiceForApplication(Core::System& system_)
: ServiceFramework{system_, "olsc:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IOlscServiceForApplication::Initialize, "Initialize"},
{10, nullptr, "VerifySaveDataBackupLicenseAsync"},
{13, &IOlscServiceForApplication::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"},
{14, &IOlscServiceForApplication::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
{15, nullptr, "SetCustomData"},
{16, nullptr, "DeleteSaveDataBackupSetting"},
{18, nullptr, "GetSaveDataBackupInfoCache"},
{19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
{22, nullptr, "DeleteSaveDataBackupAsync"},
{25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
{26, nullptr, "DownloadSaveDataBackupAsync"},
{27, nullptr, "UploadSaveDataBackupAsync"},
{9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
{9013, nullptr, "GetSaveDataBackupSettingForDebug"},
{9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
{9015, nullptr, "SetCustomDataForDebug"},
{9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
{9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
{9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
{9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
{9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
{9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void Initialize(HLERequestContext& ctx) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
initialized = true;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetSaveDataBackupSetting(HLERequestContext& ctx) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
// backup_setting is set to 0 since real value is unknown
constexpr u64 backup_setting = 0;
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push(backup_setting);
}
void SetSaveDataBackupSettingEnabled(HLERequestContext& ctx) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
bool initialized{};
};
class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
public:
explicit INativeHandleHolder(Core::System& system_)
: ServiceFramework{system_, "INativeHandleHolder"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetNativeHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
public:
explicit ITransferTaskListController(Core::System& system_)
: ServiceFramework{system_, "ITransferTaskListController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown0"},
{1, nullptr, "Unknown1"},
{2, nullptr, "Unknown2"},
{3, nullptr, "Unknown3"},
{4, nullptr, "Unknown4"},
{5, &ITransferTaskListController::GetNativeHandleHolder , "GetNativeHandleHolder"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "GetRemoteStorageController"},
{9, &ITransferTaskListController::GetNativeHandleHolder, "GetNativeHandleHolder2"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "Unknown16"},
{17, nullptr, "Unknown17"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{20, nullptr, "Unknown20"},
{21, nullptr, "Unknown21"},
{22, nullptr, "Unknown22"},
{23, nullptr, "Unknown23"},
{24, nullptr, "Unknown24"},
{25, nullptr, "Unknown25"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetNativeHandleHolder(HLERequestContext& ctx) {
LOG_INFO(Service_OLSC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<INativeHandleHolder>(system);
}
};
class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
public:
explicit IOlscServiceForSystemService(Core::System& system_)
: ServiceFramework{system_, "olsc:s"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IOlscServiceForSystemService::OpenTransferTaskListController, "OpenTransferTaskListController"},
{1, nullptr, "OpenRemoteStorageController"},
{2, nullptr, "OpenDaemonController"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{100, nullptr, "ListLastTransferTaskErrorInfo"},
{101, nullptr, "GetLastErrorInfoCount"},
{102, nullptr, "RemoveLastErrorInfoOld"},
{103, nullptr, "GetLastErrorInfo"},
{104, nullptr, "GetLastErrorEventHolder"},
{105, nullptr, "GetLastTransferTaskErrorInfo"},
{200, nullptr, "GetDataTransferPolicyInfo"},
{201, nullptr, "RemoveDataTransferPolicyInfo"},
{202, nullptr, "UpdateDataTransferPolicyOld"},
{203, nullptr, "UpdateDataTransferPolicy"},
{204, nullptr, "CleanupDataTransferPolicyInfo"},
{205, nullptr, "RequestDataTransferPolicy"},
{300, nullptr, "GetAutoTransferSeriesInfo"},
{301, nullptr, "UpdateAutoTransferSeriesInfo"},
{400, nullptr, "CleanupSaveDataArchiveInfoType1"},
{900, nullptr, "CleanupTransferTask"},
{902, nullptr, "CleanupSeriesInfoType0"},
{903, nullptr, "CleanupSaveDataArchiveInfoType0"},
{904, nullptr, "CleanupApplicationAutoTransferSetting"},
{905, nullptr, "CleanupErrorHistory"},
{906, nullptr, "SetLastError"},
{907, nullptr, "AddSaveDataArchiveInfoType0"},
{908, nullptr, "RemoveSeriesInfoType0"},
{909, nullptr, "GetSeriesInfoType0"},
{910, nullptr, "RemoveLastErrorInfo"},
{911, nullptr, "CleanupSeriesInfoType1"},
{912, nullptr, "RemoveSeriesInfoType1"},
{913, nullptr, "GetSeriesInfoType1"},
{1000, nullptr, "UpdateIssueOld"},
{1010, nullptr, "Unknown1010"},
{1011, nullptr, "ListIssueInfoOld"},
{1012, nullptr, "GetIssueOld"},
{1013, nullptr, "GetIssue2Old"},
{1014, nullptr, "GetIssue3Old"},
{1020, nullptr, "RepairIssueOld"},
{1021, nullptr, "RepairIssueWithUserIdOld"},
{1022, nullptr, "RepairIssue2Old"},
{1023, nullptr, "RepairIssue3Old"},
{1024, nullptr, "Unknown1024"},
{1100, nullptr, "UpdateIssue"},
{1110, nullptr, "Unknown1110"},
{1111, nullptr, "ListIssueInfo"},
{1112, nullptr, "GetIssue"},
{1113, nullptr, "GetIssue2"},
{1114, nullptr, "GetIssue3"},
{1120, nullptr, "RepairIssue"},
{1121, nullptr, "RepairIssueWithUserId"},
{1122, nullptr, "RepairIssue2"},
{1123, nullptr, "RepairIssue3"},
{1124, nullptr, "Unknown1124"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void OpenTransferTaskListController(HLERequestContext& ctx) {
LOG_INFO(Service_OLSC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<ITransferTaskListController>(system);
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
const auto OlscFactoryForApplication = [&] {
return std::make_shared<IOlscServiceForApplication>(system);
};
const auto OlscFactoryForSystemService = [&] {
return std::make_shared<IOlscServiceForSystemService>(system);
};
server_manager->RegisterNamedService("olsc:u", OlscFactoryForApplication);
server_manager->RegisterNamedService("olsc:s", OlscFactoryForSystemService);
server_manager->RegisterNamedService("olsc:u",
std::make_shared<IOlscServiceForApplication>(system));
server_manager->RegisterNamedService("olsc:s",
std::make_shared<IOlscServiceForSystemService>(system));
ServerManager::RunServer(std::move(server_manager));
}

View File

@@ -1,63 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/olsc_service_for_application.h"
namespace Service::OLSC {
IOlscServiceForApplication::IOlscServiceForApplication(Core::System& system_)
: ServiceFramework{system_, "olsc:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IOlscServiceForApplication::Initialize>, "Initialize"},
{10, nullptr, "VerifySaveDataBackupLicenseAsync"},
{13, D<&IOlscServiceForApplication::GetSaveDataBackupSetting>, "GetSaveDataBackupSetting"},
{14, D<&IOlscServiceForApplication::SetSaveDataBackupSettingEnabled>, "SetSaveDataBackupSettingEnabled"},
{15, nullptr, "SetCustomData"},
{16, nullptr, "DeleteSaveDataBackupSetting"},
{18, nullptr, "GetSaveDataBackupInfoCache"},
{19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
{22, nullptr, "DeleteSaveDataBackupAsync"},
{25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
{26, nullptr, "DownloadSaveDataBackupAsync"},
{27, nullptr, "UploadSaveDataBackupAsync"},
{9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
{9013, nullptr, "GetSaveDataBackupSettingForDebug"},
{9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
{9015, nullptr, "SetCustomDataForDebug"},
{9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
{9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
{9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
{9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
{9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
{9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
};
// clang-format on
RegisterHandlers(functions);
}
IOlscServiceForApplication::~IOlscServiceForApplication() = default;
Result IOlscServiceForApplication::Initialize(ClientProcessId process_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
initialized = true;
R_SUCCEED();
}
Result IOlscServiceForApplication::GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
// backup_setting is set to 0 since real value is unknown
*out_save_data_backup_setting = 0;
R_SUCCEED();
}
Result IOlscServiceForApplication::SetSaveDataBackupSettingEnabled(bool enabled,
NS::Uid account_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, enabled={}, account_id={}", enabled,
account_id.uuid.FormattedString());
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,23 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
public:
explicit IOlscServiceForApplication(Core::System& system_);
~IOlscServiceForApplication() override;
private:
Result Initialize(ClientProcessId process_id);
Result GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting);
Result SetSaveDataBackupSettingEnabled(bool enabled, NS::Uid account_id);
bool initialized{};
};
} // namespace Service::OLSC

View File

@@ -1,117 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/daemon_controller.h"
#include "core/hle/service/olsc/olsc_service_for_system_service.h"
#include "core/hle/service/olsc/remote_storage_controller.h"
#include "core/hle/service/olsc/transfer_task_list_controller.h"
namespace Service::OLSC {
IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_)
: ServiceFramework{system_, "olsc:s"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IOlscServiceForSystemService::OpenTransferTaskListController>, "OpenTransferTaskListController"},
{1, D<&IOlscServiceForSystemService::OpenRemoteStorageController>, "OpenRemoteStorageController"},
{2, D<&IOlscServiceForSystemService::OpenDaemonController>, "OpenDaemonController"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{100, nullptr, "ListLastTransferTaskErrorInfo"},
{101, nullptr, "GetLastErrorInfoCount"},
{102, nullptr, "RemoveLastErrorInfoOld"},
{103, nullptr, "GetLastErrorInfo"},
{104, nullptr, "GetLastErrorEventHolder"},
{105, nullptr, "GetLastTransferTaskErrorInfo"},
{200, D<&IOlscServiceForSystemService::GetDataTransferPolicyInfo>, "GetDataTransferPolicyInfo"},
{201, nullptr, "RemoveDataTransferPolicyInfo"},
{202, nullptr, "UpdateDataTransferPolicyOld"},
{203, nullptr, "UpdateDataTransferPolicy"},
{204, nullptr, "CleanupDataTransferPolicyInfo"},
{205, nullptr, "RequestDataTransferPolicy"},
{300, nullptr, "GetAutoTransferSeriesInfo"},
{301, nullptr, "UpdateAutoTransferSeriesInfo"},
{400, nullptr, "CleanupSaveDataArchiveInfoType1"},
{900, nullptr, "CleanupTransferTask"},
{902, nullptr, "CleanupSeriesInfoType0"},
{903, nullptr, "CleanupSaveDataArchiveInfoType0"},
{904, nullptr, "CleanupApplicationAutoTransferSetting"},
{905, nullptr, "CleanupErrorHistory"},
{906, nullptr, "SetLastError"},
{907, nullptr, "AddSaveDataArchiveInfoType0"},
{908, nullptr, "RemoveSeriesInfoType0"},
{909, nullptr, "GetSeriesInfoType0"},
{910, nullptr, "RemoveLastErrorInfo"},
{911, nullptr, "CleanupSeriesInfoType1"},
{912, nullptr, "RemoveSeriesInfoType1"},
{913, nullptr, "GetSeriesInfoType1"},
{1000, nullptr, "UpdateIssueOld"},
{1010, nullptr, "Unknown1010"},
{1011, nullptr, "ListIssueInfoOld"},
{1012, nullptr, "GetIssueOld"},
{1013, nullptr, "GetIssue2Old"},
{1014, nullptr, "GetIssue3Old"},
{1020, nullptr, "RepairIssueOld"},
{1021, nullptr, "RepairIssueWithUserIdOld"},
{1022, nullptr, "RepairIssue2Old"},
{1023, nullptr, "RepairIssue3Old"},
{1024, nullptr, "Unknown1024"},
{1100, nullptr, "UpdateIssue"},
{1110, nullptr, "Unknown1110"},
{1111, nullptr, "ListIssueInfo"},
{1112, nullptr, "GetIssue"},
{1113, nullptr, "GetIssue2"},
{1114, nullptr, "GetIssue3"},
{1120, nullptr, "RepairIssue"},
{1121, nullptr, "RepairIssueWithUserId"},
{1122, nullptr, "RepairIssue2"},
{1123, nullptr, "RepairIssue3"},
{1124, nullptr, "Unknown1124"},
{10000, D<&IOlscServiceForSystemService::CloneService>, "CloneService"},
};
// clang-format on
RegisterHandlers(functions);
}
IOlscServiceForSystemService::~IOlscServiceForSystemService() = default;
Result IOlscServiceForSystemService::OpenTransferTaskListController(
Out<SharedPointer<ITransferTaskListController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<ITransferTaskListController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::OpenRemoteStorageController(
Out<SharedPointer<IRemoteStorageController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<IRemoteStorageController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::OpenDaemonController(
Out<SharedPointer<IDaemonController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<IDaemonController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(Out<u16> out_policy_info,
u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_policy_info = 0;
R_SUCCEED();
}
Result IOlscServiceForSystemService::CloneService(
Out<SharedPointer<IOlscServiceForSystemService>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::static_pointer_cast<IOlscServiceForSystemService>(shared_from_this());
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,27 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class IDaemonController;
class IRemoteStorageController;
class ITransferTaskListController;
class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
public:
explicit IOlscServiceForSystemService(Core::System& system_);
~IOlscServiceForSystemService() override;
private:
Result OpenTransferTaskListController(
Out<SharedPointer<ITransferTaskListController>> out_interface);
Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
Result GetDataTransferPolicyInfo(Out<u16> out_policy_info, u64 application_id);
Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
};
} // namespace Service::OLSC

View File

@@ -1,54 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/remote_storage_controller.h"
namespace Service::OLSC {
IRemoteStorageController::IRemoteStorageController(Core::System& system_)
: ServiceFramework{system_, "IRemoteStorageController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetSaveDataArchiveInfoBySaveDataId"},
{1, nullptr, "GetSaveDataArchiveInfoByApplicationId"},
{3, nullptr, "GetSaveDataArchiveCount"},
{6, nullptr, "CleanupSaveDataArchives"},
{7, nullptr, "CreateSaveDataArchiveCacheUpdationTask"},
{8, nullptr, "CreateSaveDataArchiveCacheUpdationForSpecifiedApplicationTask"},
{9, nullptr, "Delete"},
{10, nullptr, "GetSeriesInfo"},
{11, nullptr, "CreateDeleteDataTask"},
{12, nullptr, "DeleteSeriesInfo"},
{13, nullptr, "CreateRegisterNotificationTokenTask"},
{14, nullptr, "UpdateSeriesInfo"},
{15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"},
{16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"},
{17, nullptr, "ListDataInfo"},
{18, nullptr, "GetDataInfo"},
{19, nullptr, "Unknown19"},
{20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"},
{21, nullptr, "ListSecondarySaves"},
{22, D<&IRemoteStorageController::GetSecondarySave>, "GetSecondarySave"},
{23, nullptr, "TouchSecondarySave"},
{24, nullptr, "GetSecondarySaveDataInfo"},
{25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"},
{900, nullptr, "Unknown900"},
};
// clang-format on
RegisterHandlers(functions);
}
IRemoteStorageController::~IRemoteStorageController() = default;
Result IRemoteStorageController::GetSecondarySave(Out<bool> out_has_secondary_save,
Out<std::array<u64, 3>> out_unknown,
u64 application_id) {
LOG_ERROR(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
*out_has_secondary_save = false;
*out_unknown = {};
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,19 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class IRemoteStorageController final : public ServiceFramework<IRemoteStorageController> {
public:
explicit IRemoteStorageController(Core::System& system_);
~IRemoteStorageController() override;
private:
Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown,
u64 application_id);
};
} // namespace Service::OLSC

View File

@@ -1,55 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/native_handle_holder.h"
#include "core/hle/service/olsc/transfer_task_list_controller.h"
namespace Service::OLSC {
ITransferTaskListController::ITransferTaskListController(Core::System& system_)
: ServiceFramework{system_, "ITransferTaskListController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown0"},
{1, nullptr, "Unknown1"},
{2, nullptr, "Unknown2"},
{3, nullptr, "Unknown3"},
{4, nullptr, "Unknown4"},
{5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "GetRemoteStorageController"},
{9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "Unknown16"},
{17, nullptr, "Unknown17"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{20, nullptr, "Unknown20"},
{21, nullptr, "Unknown21"},
{22, nullptr, "Unknown22"},
{23, nullptr, "Unknown23"},
{24, nullptr, "Unknown24"},
{25, nullptr, "Unknown25"},
};
// clang-format on
RegisterHandlers(functions);
}
ITransferTaskListController::~ITransferTaskListController() = default;
Result ITransferTaskListController::GetNativeHandleHolder(
Out<SharedPointer<INativeHandleHolder>> out_holder) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_holder = std::make_shared<INativeHandleHolder>(system);
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,20 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::OLSC {
class INativeHandleHolder;
class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
public:
explicit ITransferTaskListController(Core::System& system_);
~ITransferTaskListController() override;
private:
Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
};
} // namespace Service::OLSC

View File

@@ -1,434 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/pctl/parental_control_service.h"
#include "core/hle/service/pctl/pctl_results.h"
namespace Service::PCTL {
IParentalControlService::IParentalControlService(Core::System& system_, Capability capability_)
: ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
service_context{system_, "IParentalControlService"}, synchronization_event{service_context},
unlinked_event{service_context}, request_suspension_event{service_context} {
// clang-format off
static const FunctionInfo functions[] = {
{1, D<&IParentalControlService::Initialize>, "Initialize"},
{1001, D<&IParentalControlService::CheckFreeCommunicationPermission>, "CheckFreeCommunicationPermission"},
{1002, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"},
{1003, D<&IParentalControlService::ConfirmResumeApplicationPermission>, "ConfirmResumeApplicationPermission"},
{1004, D<&IParentalControlService::ConfirmSnsPostPermission>, "ConfirmSnsPostPermission"},
{1005, nullptr, "ConfirmSystemSettingsPermission"},
{1006, D<&IParentalControlService::IsRestrictionTemporaryUnlocked>, "IsRestrictionTemporaryUnlocked"},
{1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
{1008, nullptr, "EnterRestrictedSystemSettings"},
{1009, nullptr, "LeaveRestrictedSystemSettings"},
{1010, D<&IParentalControlService::IsRestrictedSystemSettingsEntered>, "IsRestrictedSystemSettingsEntered"},
{1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
{1012, nullptr, "GetRestrictedFeatures"},
{1013, D<&IParentalControlService::ConfirmStereoVisionPermission>, "ConfirmStereoVisionPermission"},
{1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
{1015, nullptr, "ConfirmPlayableApplicationVideo"},
{1016, nullptr, "ConfirmShowNewsPermission"},
{1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
{1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
{1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
{1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
{1033, nullptr, "SetSafetyLevel"},
{1034, nullptr, "GetSafetyLevelSettings"},
{1035, D<&IParentalControlService::GetCurrentSettings>, "GetCurrentSettings"},
{1036, nullptr, "SetCustomSafetyLevelSettings"},
{1037, nullptr, "GetDefaultRatingOrganization"},
{1038, nullptr, "SetDefaultRatingOrganization"},
{1039, D<&IParentalControlService::GetFreeCommunicationApplicationListCount>, "GetFreeCommunicationApplicationListCount"},
{1042, nullptr, "AddToFreeCommunicationApplicationList"},
{1043, nullptr, "DeleteSettings"},
{1044, nullptr, "GetFreeCommunicationApplicationList"},
{1045, nullptr, "UpdateFreeCommunicationApplicationList"},
{1046, nullptr, "DisableFeaturesForReset"},
{1047, nullptr, "NotifyApplicationDownloadStarted"},
{1048, nullptr, "NotifyNetworkProfileCreated"},
{1049, nullptr, "ResetFreeCommunicationApplicationList"},
{1061, D<&IParentalControlService::ConfirmStereoVisionRestrictionConfigurable>, "ConfirmStereoVisionRestrictionConfigurable"},
{1062, D<&IParentalControlService::GetStereoVisionRestriction>, "GetStereoVisionRestriction"},
{1063, D<&IParentalControlService::SetStereoVisionRestriction>, "SetStereoVisionRestriction"},
{1064, D<&IParentalControlService::ResetConfirmedStereoVisionPermission>, "ResetConfirmedStereoVisionPermission"},
{1065, D<&IParentalControlService::IsStereoVisionPermitted>, "IsStereoVisionPermitted"},
{1201, nullptr, "UnlockRestrictionTemporarily"},
{1202, nullptr, "UnlockSystemSettingsRestriction"},
{1203, nullptr, "SetPinCode"},
{1204, nullptr, "GenerateInquiryCode"},
{1205, nullptr, "CheckMasterKey"},
{1206, D<&IParentalControlService::GetPinCodeLength>, "GetPinCodeLength"},
{1207, nullptr, "GetPinCodeChangedEvent"},
{1208, nullptr, "GetPinCode"},
{1403, D<&IParentalControlService::IsPairingActive>, "IsPairingActive"},
{1406, nullptr, "GetSettingsLastUpdated"},
{1411, nullptr, "GetPairingAccountInfo"},
{1421, nullptr, "GetAccountNickname"},
{1424, nullptr, "GetAccountState"},
{1425, nullptr, "RequestPostEvents"},
{1426, nullptr, "GetPostEventInterval"},
{1427, nullptr, "SetPostEventInterval"},
{1432, D<&IParentalControlService::GetSynchronizationEvent>, "GetSynchronizationEvent"},
{1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"},
{1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"},
{1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"},
{1454, nullptr, "GetPlayTimerRemainingTime"},
{1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"},
{1456, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"},
{1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"},
{1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"},
{1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
{1472, nullptr, "CancelNetworkRequest"},
{1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"},
{1474, nullptr, "ClearUnlinkedEvent"},
{1601, nullptr, "DisableAllFeatures"},
{1602, nullptr, "PostEnableAllFeatures"},
{1603, nullptr, "IsAllFeaturesDisabled"},
{1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
{1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
{1903, nullptr, "GetExemptApplicationListCountForDebug"},
{1904, nullptr, "GetExemptApplicationListForDebug"},
{1905, nullptr, "UpdateExemptApplicationListForDebug"},
{1906, nullptr, "AddToExemptApplicationListForDebug"},
{1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
{1908, nullptr, "ClearExemptApplicationListForDebug"},
{1941, nullptr, "DeletePairing"},
{1951, nullptr, "SetPlayTimerSettingsForDebug"},
{1952, nullptr, "GetPlayTimerSpentTimeForTest"},
{1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
{2001, nullptr, "RequestPairingAsync"},
{2002, nullptr, "FinishRequestPairing"},
{2003, nullptr, "AuthorizePairingAsync"},
{2004, nullptr, "FinishAuthorizePairing"},
{2005, nullptr, "RetrievePairingInfoAsync"},
{2006, nullptr, "FinishRetrievePairingInfo"},
{2007, nullptr, "UnlinkPairingAsync"},
{2008, nullptr, "FinishUnlinkPairing"},
{2009, nullptr, "GetAccountMiiImageAsync"},
{2010, nullptr, "FinishGetAccountMiiImage"},
{2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
{2012, nullptr, "FinishGetAccountMiiImageContentType"},
{2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
{2014, nullptr, "FinishSynchronizeParentalControlSettings"},
{2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
{2016, nullptr, "RequestUpdateExemptionListAsync"},
};
// clang-format on
RegisterHandlers(functions);
}
IParentalControlService::~IParentalControlService() = default;
bool IParentalControlService::CheckFreeCommunicationPermissionImpl() const {
if (states.temporary_unlocked) {
return true;
}
if ((states.application_info.parental_control_flag & 1) == 0) {
return true;
}
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_free_communication_default_on) {
return true;
}
// TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
// but as we don't have multiproceses support yet, we can just assume our application is
// valid for the time being
return true;
}
bool IParentalControlService::ConfirmStereoVisionPermissionImpl() const {
if (states.temporary_unlocked) {
return true;
}
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_stero_vision_restricted) {
return false;
}
return true;
}
void IParentalControlService::SetStereoVisionRestrictionImpl(bool is_restricted) {
if (settings.disabled) {
return;
}
if (pin_code[0] == '\0') {
return;
}
settings.is_stero_vision_restricted = is_restricted;
}
Result IParentalControlService::Initialize() {
LOG_DEBUG(Service_PCTL, "called");
if (False(capability & (Capability::Application | Capability::System))) {
LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
R_THROW(PCTL::ResultNoCapability);
}
// TODO(ogniK): Recovery flag initialization for pctl:r
const auto program_id = system.GetApplicationProcessProgramID();
if (program_id != 0) {
const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
if (control.first) {
states.tid_from_event = 0;
states.launch_time_valid = false;
states.is_suspended = false;
states.free_communication = false;
states.stereo_vision = false;
states.application_info = ApplicationInfo{
.application_id = program_id,
.age_rating = control.first->GetRatingAge(),
.parental_control_flag = control.first->GetParentalControlFlag(),
.capability = capability,
};
if (False(capability & (Capability::System | Capability::Recovery))) {
// TODO(ogniK): Signal application launch event
}
}
}
R_SUCCEED();
}
Result IParentalControlService::CheckFreeCommunicationPermission() {
LOG_DEBUG(Service_PCTL, "called");
if (!CheckFreeCommunicationPermissionImpl()) {
R_THROW(PCTL::ResultNoFreeCommunication);
} else {
states.free_communication = true;
R_SUCCEED();
}
}
Result IParentalControlService::ConfirmLaunchApplicationPermission(
InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
application_id);
R_SUCCEED();
}
Result IParentalControlService::ConfirmResumeApplicationPermission(
InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) {
LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag,
application_id);
R_SUCCEED();
}
Result IParentalControlService::ConfirmSnsPostPermission() {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
R_THROW(PCTL::ResultNoFreeCommunication);
}
Result IParentalControlService::IsRestrictionTemporaryUnlocked(
Out<bool> out_is_temporary_unlocked) {
*out_is_temporary_unlocked = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
*out_is_temporary_unlocked);
R_SUCCEED();
}
Result IParentalControlService::IsRestrictedSystemSettingsEntered(
Out<bool> out_is_restricted_system_settings_entered) {
*out_is_restricted_system_settings_entered = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
*out_is_restricted_system_settings_entered);
R_SUCCEED();
}
Result IParentalControlService::ConfirmStereoVisionPermission() {
LOG_DEBUG(Service_PCTL, "called");
states.stereo_vision = true;
R_SUCCEED();
}
Result IParentalControlService::EndFreeCommunication() {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
R_SUCCEED();
}
Result IParentalControlService::IsFreeCommunicationAvailable() {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
if (!CheckFreeCommunicationPermissionImpl()) {
R_THROW(PCTL::ResultNoFreeCommunication);
} else {
R_SUCCEED();
}
}
Result IParentalControlService::IsRestrictionEnabled(Out<bool> out_restriction_enabled) {
LOG_DEBUG(Service_PCTL, "called");
if (False(capability & (Capability::Status | Capability::Recovery))) {
LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
*out_restriction_enabled = false;
R_THROW(PCTL::ResultNoCapability);
}
*out_restriction_enabled = pin_code[0] != '\0';
R_SUCCEED();
}
Result IParentalControlService::GetSafetyLevel(Out<u32> out_safety_level) {
*out_safety_level = 0;
LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", *out_safety_level);
R_SUCCEED();
}
Result IParentalControlService::GetCurrentSettings(Out<RestrictionSettings> out_settings) {
LOG_INFO(Service_PCTL, "called");
*out_settings = restriction_settings;
R_SUCCEED();
}
Result IParentalControlService::GetFreeCommunicationApplicationListCount(Out<s32> out_count) {
*out_count = 4;
LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", *out_count);
R_SUCCEED();
}
Result IParentalControlService::ConfirmStereoVisionRestrictionConfigurable() {
LOG_DEBUG(Service_PCTL, "called");
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
R_THROW(PCTL::ResultNoCapability);
}
if (pin_code[0] == '\0') {
R_THROW(PCTL::ResultNoRestrictionEnabled);
}
R_SUCCEED();
}
Result IParentalControlService::IsStereoVisionPermitted(Out<bool> out_is_permitted) {
LOG_DEBUG(Service_PCTL, "called");
if (!ConfirmStereoVisionPermissionImpl()) {
*out_is_permitted = false;
R_THROW(PCTL::ResultStereoVisionRestricted);
} else {
*out_is_permitted = true;
R_SUCCEED();
}
}
Result IParentalControlService::GetPinCodeLength(Out<s32> out_length) {
*out_length = 0;
LOG_WARNING(Service_PCTL, "(STUBBED) called, length={}", *out_length);
R_SUCCEED();
}
Result IParentalControlService::IsPairingActive(Out<bool> out_is_pairing_active) {
*out_is_pairing_active = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", *out_is_pairing_active);
R_SUCCEED();
}
Result IParentalControlService::GetSynchronizationEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_PCTL, "called");
*out_event = synchronization_event.GetHandle();
R_SUCCEED();
}
Result IParentalControlService::StartPlayTimer() {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
R_SUCCEED();
}
Result IParentalControlService::StopPlayTimer() {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
R_SUCCEED();
}
Result IParentalControlService::IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled) {
*out_is_play_timer_enabled = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, enabled={}", *out_is_play_timer_enabled);
R_SUCCEED();
}
Result IParentalControlService::IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer) {
*out_is_restricted_by_play_timer = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, restricted={}", *out_is_restricted_by_play_timer);
R_SUCCEED();
}
Result IParentalControlService::GetPlayTimerSettings(
Out<PlayTimerSettings> out_play_timer_settings) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
*out_play_timer_settings = {};
R_SUCCEED();
}
Result IParentalControlService::GetPlayTimerEventToRequestSuspension(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_PCTL, "called");
*out_event = request_suspension_event.GetHandle();
R_SUCCEED();
}
Result IParentalControlService::IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled) {
*out_play_timer_alarm_disabled = false;
LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
*out_play_timer_alarm_disabled);
R_SUCCEED();
}
Result IParentalControlService::GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_PCTL, "called");
*out_event = unlinked_event.GetHandle();
R_SUCCEED();
}
Result IParentalControlService::GetStereoVisionRestriction(
Out<bool> out_stereo_vision_restriction) {
LOG_DEBUG(Service_PCTL, "called");
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
*out_stereo_vision_restriction = false;
R_THROW(PCTL::ResultNoCapability);
}
*out_stereo_vision_restriction = settings.is_stero_vision_restricted;
R_SUCCEED();
}
Result IParentalControlService::SetStereoVisionRestriction(bool stereo_vision_restriction) {
LOG_DEBUG(Service_PCTL, "called, can_use={}", stereo_vision_restriction);
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
R_THROW(PCTL::ResultNoCapability);
}
SetStereoVisionRestrictionImpl(stereo_vision_restriction);
R_SUCCEED();
}
Result IParentalControlService::ResetConfirmedStereoVisionPermission() {
LOG_DEBUG(Service_PCTL, "called");
states.stereo_vision = false;
R_SUCCEED();
}
} // namespace Service::PCTL

View File

@@ -1,86 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/os/event.h"
#include "core/hle/service/pctl/pctl_types.h"
#include "core/hle/service/service.h"
namespace Service::PCTL {
class IParentalControlService final : public ServiceFramework<IParentalControlService> {
public:
explicit IParentalControlService(Core::System& system_, Capability capability_);
~IParentalControlService() override;
private:
bool CheckFreeCommunicationPermissionImpl() const;
bool ConfirmStereoVisionPermissionImpl() const;
void SetStereoVisionRestrictionImpl(bool is_restricted);
Result Initialize();
Result CheckFreeCommunicationPermission();
Result ConfirmLaunchApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
u64 nacp_flag, u64 application_id);
Result ConfirmResumeApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset,
u64 nacp_flag, u64 application_id);
Result ConfirmSnsPostPermission();
Result IsRestrictionTemporaryUnlocked(Out<bool> out_is_temporary_unlocked);
Result IsRestrictedSystemSettingsEntered(Out<bool> out_is_restricted_system_settings_entered);
Result ConfirmStereoVisionPermission();
Result EndFreeCommunication();
Result IsFreeCommunicationAvailable();
Result IsRestrictionEnabled(Out<bool> out_restriction_enabled);
Result GetSafetyLevel(Out<u32> out_safety_level);
Result GetCurrentSettings(Out<RestrictionSettings> out_settings);
Result GetFreeCommunicationApplicationListCount(Out<s32> out_count);
Result ConfirmStereoVisionRestrictionConfigurable();
Result IsStereoVisionPermitted(Out<bool> out_is_permitted);
Result GetPinCodeLength(Out<s32> out_length);
Result IsPairingActive(Out<bool> out_is_pairing_active);
Result GetSynchronizationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result StartPlayTimer();
Result StopPlayTimer();
Result IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled);
Result IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer);
Result GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings);
Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled);
Result GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction);
Result SetStereoVisionRestriction(bool stereo_vision_restriction);
Result ResetConfirmedStereoVisionPermission();
struct States {
u64 current_tid{};
ApplicationInfo application_info{};
u64 tid_from_event{};
bool launch_time_valid{};
bool is_suspended{};
bool temporary_unlocked{};
bool free_communication{};
bool stereo_vision{};
};
struct ParentalControlSettings {
bool is_stero_vision_restricted{};
bool is_free_communication_default_on{};
bool disabled{};
};
States states{};
ParentalControlSettings settings{};
RestrictionSettings restriction_settings{};
std::array<char, 8> pin_code{};
Capability capability{};
KernelHelpers::ServiceContext service_context;
Event synchronization_event;
Event unlinked_event;
Event request_suspension_event;
};
} // namespace Service::PCTL

View File

@@ -1,40 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/pctl/parental_control_service.h"
#include "core/hle/service/pctl/parental_control_service_factory.h"
namespace Service::PCTL {
IParentalControlServiceFactory::IParentalControlServiceFactory(Core::System& system_,
const char* name_,
Capability capability_)
: ServiceFramework{system_, name_}, capability{capability_} {
static const FunctionInfo functions[] = {
{0, D<&IParentalControlServiceFactory::CreateService>, "CreateService"},
{1, D<&IParentalControlServiceFactory::CreateServiceWithoutInitialize>,
"CreateServiceWithoutInitialize"},
};
RegisterHandlers(functions);
}
IParentalControlServiceFactory::~IParentalControlServiceFactory() = default;
Result IParentalControlServiceFactory::CreateService(
Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
LOG_DEBUG(Service_PCTL, "called");
// TODO(ogniK): Get application id from process
*out_service = std::make_shared<IParentalControlService>(system, capability);
R_SUCCEED();
}
Result IParentalControlServiceFactory::CreateServiceWithoutInitialize(
Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) {
LOG_DEBUG(Service_PCTL, "called");
// TODO(ogniK): Get application id from process
*out_service = std::make_shared<IParentalControlService>(system, capability);
R_SUCCEED();
}
} // namespace Service::PCTL

View File

@@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/pctl/pctl_types.h"
#include "core/hle/service/service.h"
namespace Service::PCTL {
class IParentalControlService;
class IParentalControlServiceFactory : public ServiceFramework<IParentalControlServiceFactory> {
public:
explicit IParentalControlServiceFactory(Core::System& system_, const char* name_,
Capability capability_);
~IParentalControlServiceFactory() override;
Result CreateService(Out<SharedPointer<IParentalControlService>> out_service,
ClientProcessId process_id);
Result CreateServiceWithoutInitialize(Out<SharedPointer<IParentalControlService>> out_service,
ClientProcessId process_id);
private:
Capability capability{};
};
void LoopProcess(Core::System& system);
} // namespace Service::PCTL

View File

@@ -1,28 +1,19 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/pctl/parental_control_service_factory.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/server_manager.h"
namespace Service::PCTL {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("pctl",
std::make_shared<IParentalControlServiceFactory>(
system, "pctl",
Capability::Application | Capability::SnsPost |
Capability::Status | Capability::StereoVision));
// TODO(ogniK): Implement remaining capabilities
server_manager->RegisterNamedService("pctl:a", std::make_shared<IParentalControlServiceFactory>(
system, "pctl:a", Capability::None));
server_manager->RegisterNamedService("pctl:r", std::make_shared<IParentalControlServiceFactory>(
system, "pctl:r", Capability::None));
server_manager->RegisterNamedService("pctl:s", std::make_shared<IParentalControlServiceFactory>(
system, "pctl:s", Capability::None));
ServerManager::RunServer(std::move(server_manager));
PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
Capability capability_)
: Interface{system_, std::move(module_), name, capability_} {
static const FunctionInfo functions[] = {
{0, &PCTL::CreateService, "CreateService"},
{1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"},
};
RegisterHandlers(functions);
}
PCTL::~PCTL() = default;
} // namespace Service::PCTL

View File

@@ -3,12 +3,19 @@
#pragma once
#include "core/hle/service/pctl/pctl_module.h"
namespace Core {
class System;
}
namespace Service::PCTL {
void LoopProcess(Core::System& system);
class PCTL final : public Module::Interface {
public:
explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
Capability capability_);
~PCTL() override;
};
} // namespace Service::PCTL

View File

@@ -0,0 +1,550 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/pctl/pctl_module.h"
#include "core/hle/service/server_manager.h"
namespace Service::PCTL {
namespace Error {
constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101};
constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
constexpr Result ResultNoCapability{ErrorModule::PCTL, 131};
constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
} // namespace Error
class IParentalControlService final : public ServiceFramework<IParentalControlService> {
public:
explicit IParentalControlService(Core::System& system_, Capability capability_)
: ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
service_context{system_, "IParentalControlService"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IParentalControlService::Initialize, "Initialize"},
{1001, &IParentalControlService::CheckFreeCommunicationPermission, "CheckFreeCommunicationPermission"},
{1002, nullptr, "ConfirmLaunchApplicationPermission"},
{1003, nullptr, "ConfirmResumeApplicationPermission"},
{1004, &IParentalControlService::ConfirmSnsPostPermission, "ConfirmSnsPostPermission"},
{1005, nullptr, "ConfirmSystemSettingsPermission"},
{1006, &IParentalControlService::IsRestrictionTemporaryUnlocked, "IsRestrictionTemporaryUnlocked"},
{1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
{1008, nullptr, "EnterRestrictedSystemSettings"},
{1009, nullptr, "LeaveRestrictedSystemSettings"},
{1010, nullptr, "IsRestrictedSystemSettingsEntered"},
{1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
{1012, nullptr, "GetRestrictedFeatures"},
{1013, &IParentalControlService::ConfirmStereoVisionPermission, "ConfirmStereoVisionPermission"},
{1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
{1015, nullptr, "ConfirmPlayableApplicationVideo"},
{1016, nullptr, "ConfirmShowNewsPermission"},
{1017, &IParentalControlService::EndFreeCommunication, "EndFreeCommunication"},
{1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"},
{1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"},
{1032, &IParentalControlService::GetSafetyLevel, "GetSafetyLevel"},
{1033, nullptr, "SetSafetyLevel"},
{1034, nullptr, "GetSafetyLevelSettings"},
{1035, &IParentalControlService::GetCurrentSettings, "GetCurrentSettings"},
{1036, nullptr, "SetCustomSafetyLevelSettings"},
{1037, nullptr, "GetDefaultRatingOrganization"},
{1038, nullptr, "SetDefaultRatingOrganization"},
{1039, &IParentalControlService::GetFreeCommunicationApplicationListCount, "GetFreeCommunicationApplicationListCount"},
{1042, nullptr, "AddToFreeCommunicationApplicationList"},
{1043, nullptr, "DeleteSettings"},
{1044, nullptr, "GetFreeCommunicationApplicationList"},
{1045, nullptr, "UpdateFreeCommunicationApplicationList"},
{1046, nullptr, "DisableFeaturesForReset"},
{1047, nullptr, "NotifyApplicationDownloadStarted"},
{1048, nullptr, "NotifyNetworkProfileCreated"},
{1049, nullptr, "ResetFreeCommunicationApplicationList"},
{1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"},
{1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"},
{1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"},
{1064, &IParentalControlService::ResetConfirmedStereoVisionPermission, "ResetConfirmedStereoVisionPermission"},
{1065, &IParentalControlService::IsStereoVisionPermitted, "IsStereoVisionPermitted"},
{1201, nullptr, "UnlockRestrictionTemporarily"},
{1202, nullptr, "UnlockSystemSettingsRestriction"},
{1203, nullptr, "SetPinCode"},
{1204, nullptr, "GenerateInquiryCode"},
{1205, nullptr, "CheckMasterKey"},
{1206, nullptr, "GetPinCodeLength"},
{1207, nullptr, "GetPinCodeChangedEvent"},
{1208, nullptr, "GetPinCode"},
{1403, &IParentalControlService::IsPairingActive, "IsPairingActive"},
{1406, nullptr, "GetSettingsLastUpdated"},
{1411, nullptr, "GetPairingAccountInfo"},
{1421, nullptr, "GetAccountNickname"},
{1424, nullptr, "GetAccountState"},
{1425, nullptr, "RequestPostEvents"},
{1426, nullptr, "GetPostEventInterval"},
{1427, nullptr, "SetPostEventInterval"},
{1432, &IParentalControlService::GetSynchronizationEvent, "GetSynchronizationEvent"},
{1451, nullptr, "StartPlayTimer"},
{1452, nullptr, "StopPlayTimer"},
{1453, nullptr, "IsPlayTimerEnabled"},
{1454, nullptr, "GetPlayTimerRemainingTime"},
{1455, nullptr, "IsRestrictedByPlayTimer"},
{1456, &IParentalControlService::GetPlayTimerSettings, "GetPlayTimerSettings"},
{1457, &IParentalControlService::GetPlayTimerEventToRequestSuspension, "GetPlayTimerEventToRequestSuspension"},
{1458, &IParentalControlService::IsPlayTimerAlarmDisabled, "IsPlayTimerAlarmDisabled"},
{1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
{1472, nullptr, "CancelNetworkRequest"},
{1473, &IParentalControlService::GetUnlinkedEvent, "GetUnlinkedEvent"},
{1474, nullptr, "ClearUnlinkedEvent"},
{1601, nullptr, "DisableAllFeatures"},
{1602, nullptr, "PostEnableAllFeatures"},
{1603, nullptr, "IsAllFeaturesDisabled"},
{1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
{1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
{1903, nullptr, "GetExemptApplicationListCountForDebug"},
{1904, nullptr, "GetExemptApplicationListForDebug"},
{1905, nullptr, "UpdateExemptApplicationListForDebug"},
{1906, nullptr, "AddToExemptApplicationListForDebug"},
{1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
{1908, nullptr, "ClearExemptApplicationListForDebug"},
{1941, nullptr, "DeletePairing"},
{1951, nullptr, "SetPlayTimerSettingsForDebug"},
{1952, nullptr, "GetPlayTimerSpentTimeForTest"},
{1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
{2001, nullptr, "RequestPairingAsync"},
{2002, nullptr, "FinishRequestPairing"},
{2003, nullptr, "AuthorizePairingAsync"},
{2004, nullptr, "FinishAuthorizePairing"},
{2005, nullptr, "RetrievePairingInfoAsync"},
{2006, nullptr, "FinishRetrievePairingInfo"},
{2007, nullptr, "UnlinkPairingAsync"},
{2008, nullptr, "FinishUnlinkPairing"},
{2009, nullptr, "GetAccountMiiImageAsync"},
{2010, nullptr, "FinishGetAccountMiiImage"},
{2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
{2012, nullptr, "FinishGetAccountMiiImageContentType"},
{2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
{2014, nullptr, "FinishSynchronizeParentalControlSettings"},
{2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
{2016, nullptr, "RequestUpdateExemptionListAsync"},
};
// clang-format on
RegisterHandlers(functions);
synchronization_event =
service_context.CreateEvent("IParentalControlService::SynchronizationEvent");
unlinked_event = service_context.CreateEvent("IParentalControlService::UnlinkedEvent");
request_suspension_event =
service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent");
}
~IParentalControlService() {
service_context.CloseEvent(synchronization_event);
service_context.CloseEvent(unlinked_event);
service_context.CloseEvent(request_suspension_event);
};
private:
bool CheckFreeCommunicationPermissionImpl() const {
if (states.temporary_unlocked) {
return true;
}
if ((states.application_info.parental_control_flag & 1) == 0) {
return true;
}
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_free_communication_default_on) {
return true;
}
// TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
// but as we don't have multiproceses support yet, we can just assume our application is
// valid for the time being
return true;
}
bool ConfirmStereoVisionPermissionImpl() const {
if (states.temporary_unlocked) {
return true;
}
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_stero_vision_restricted) {
return false;
}
return true;
}
void SetStereoVisionRestrictionImpl(bool is_restricted) {
if (settings.disabled) {
return;
}
if (pin_code[0] == '\0') {
return;
}
settings.is_stero_vision_restricted = is_restricted;
}
void Initialize(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2};
if (False(capability & (Capability::Application | Capability::System))) {
LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
return;
}
// TODO(ogniK): Recovery flag initialization for pctl:r
const auto tid = system.GetApplicationProcessProgramID();
if (tid != 0) {
const FileSys::PatchManager pm{tid, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
if (control.first) {
states.tid_from_event = 0;
states.launch_time_valid = false;
states.is_suspended = false;
states.free_communication = false;
states.stereo_vision = false;
states.application_info = ApplicationInfo{
.tid = tid,
.age_rating = control.first->GetRatingAge(),
.parental_control_flag = control.first->GetParentalControlFlag(),
.capability = capability,
};
if (False(capability & (Capability::System | Capability::Recovery))) {
// TODO(ogniK): Signal application launch event
}
}
}
rb.Push(ResultSuccess);
}
void CheckFreeCommunicationPermission(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2};
if (!CheckFreeCommunicationPermissionImpl()) {
rb.Push(Error::ResultNoFreeCommunication);
} else {
rb.Push(ResultSuccess);
}
states.free_communication = true;
}
void ConfirmSnsPostPermission(HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(Error::ResultNoFreeCommunication);
}
void IsRestrictionTemporaryUnlocked(HLERequestContext& ctx) {
const bool is_temporary_unlocked = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
is_temporary_unlocked);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_temporary_unlocked);
}
void ConfirmStereoVisionPermission(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
states.stereo_vision = true;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void EndFreeCommunication(HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IsFreeCommunicationAvailable(HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
if (!CheckFreeCommunicationPermissionImpl()) {
rb.Push(Error::ResultNoFreeCommunication);
} else {
rb.Push(ResultSuccess);
}
}
void IsRestrictionEnabled(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
if (False(capability & (Capability::Status | Capability::Recovery))) {
LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
rb.Push(Error::ResultNoCapability);
rb.Push(false);
return;
}
rb.Push(pin_code[0] != '\0');
}
void GetSafetyLevel(HLERequestContext& ctx) {
const u32 safety_level = 0;
LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", safety_level);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(safety_level);
}
void GetCurrentSettings(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(restriction_settings);
}
void GetFreeCommunicationApplicationListCount(HLERequestContext& ctx) {
const u32 count = 4;
LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", count);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(count);
}
void ConfirmStereoVisionRestrictionConfigurable(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2};
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
rb.Push(Error::ResultNoCapability);
return;
}
if (pin_code[0] == '\0') {
rb.Push(Error::ResultNoRestrictionEnabled);
return;
}
rb.Push(ResultSuccess);
}
void IsStereoVisionPermitted(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
if (!ConfirmStereoVisionPermissionImpl()) {
rb.Push(Error::ResultStereoVisionRestricted);
rb.Push(false);
} else {
rb.Push(ResultSuccess);
rb.Push(true);
}
}
void IsPairingActive(HLERequestContext& ctx) {
const bool is_pairing_active = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", is_pairing_active);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_pairing_active);
}
void GetSynchronizationEvent(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(synchronization_event->GetReadableEvent());
}
void GetPlayTimerSettings(HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
const PlayTimerSettings timer_settings{};
IPC::ResponseBuilder rb{ctx, 15};
rb.Push(ResultSuccess);
rb.PushRaw(timer_settings);
}
void GetPlayTimerEventToRequestSuspension(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(request_suspension_event->GetReadableEvent());
}
void IsPlayTimerAlarmDisabled(HLERequestContext& ctx) {
const bool is_play_timer_alarm_disabled = false;
LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
is_play_timer_alarm_disabled);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_play_timer_alarm_disabled);
}
void GetUnlinkedEvent(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(unlinked_event->GetReadableEvent());
}
void SetStereoVisionRestriction(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_use = rp.Pop<bool>();
LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use);
IPC::ResponseBuilder rb{ctx, 2};
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
rb.Push(Error::ResultNoCapability);
return;
}
SetStereoVisionRestrictionImpl(can_use);
rb.Push(ResultSuccess);
}
void GetStereoVisionRestriction(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
if (False(capability & Capability::StereoVision)) {
LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
rb.Push(Error::ResultNoCapability);
rb.Push(false);
return;
}
rb.Push(ResultSuccess);
rb.Push(settings.is_stero_vision_restricted);
}
void ResetConfirmedStereoVisionPermission(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
states.stereo_vision = false;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
struct ApplicationInfo {
u64 tid{};
std::array<u8, 32> age_rating{};
u32 parental_control_flag{};
Capability capability{};
};
struct States {
u64 current_tid{};
ApplicationInfo application_info{};
u64 tid_from_event{};
bool launch_time_valid{};
bool is_suspended{};
bool temporary_unlocked{};
bool free_communication{};
bool stereo_vision{};
};
struct ParentalControlSettings {
bool is_stero_vision_restricted{};
bool is_free_communication_default_on{};
bool disabled{};
};
// This is nn::pctl::RestrictionSettings
struct RestrictionSettings {
u8 rating_age;
bool sns_post_restriction;
bool free_communication_restriction;
};
static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
// This is nn::pctl::PlayTimerSettings
struct PlayTimerSettings {
std::array<u32, 13> settings;
};
static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
States states{};
ParentalControlSettings settings{};
RestrictionSettings restriction_settings{};
std::array<char, 8> pin_code{};
Capability capability{};
Kernel::KEvent* synchronization_event;
Kernel::KEvent* unlinked_event;
Kernel::KEvent* request_suspension_event;
KernelHelpers::ServiceContext service_context;
};
void Module::Interface::CreateService(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
// TODO(ogniK): Get TID from process
rb.PushIpcInterface<IParentalControlService>(system, capability);
}
void Module::Interface::CreateServiceWithoutInitialize(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IParentalControlService>(system, capability);
}
Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
const char* name_, Capability capability_)
: ServiceFramework{system_, name_}, module{std::move(module_)}, capability{capability_} {}
Module::Interface::~Interface() = default;
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
auto module = std::make_shared<Module>();
server_manager->RegisterNamedService(
"pctl", std::make_shared<PCTL>(system, module, "pctl",
Capability::Application | Capability::SnsPost |
Capability::Status | Capability::StereoVision));
// TODO(ogniK): Implement remaining capabilities
server_manager->RegisterNamedService(
"pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None));
server_manager->RegisterNamedService(
"pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None));
server_manager->RegisterNamedService(
"pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None));
ServerManager::RunServer(std::move(server_manager));
}
} // namespace Service::PCTL

View File

@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_funcs.h"
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::PCTL {
enum class Capability : u32 {
None = 0,
Application = 1 << 0,
SnsPost = 1 << 1,
Recovery = 1 << 6,
Status = 1 << 8,
StereoVision = 1 << 9,
System = 1 << 15,
};
DECLARE_ENUM_FLAG_OPERATORS(Capability);
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
explicit Interface(Core::System& system_, std::shared_ptr<Module> module_,
const char* name_, Capability capability_);
~Interface() override;
void CreateService(HLERequestContext& ctx);
void CreateServiceWithoutInitialize(HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
private:
Capability capability{};
};
};
void LoopProcess(Core::System& system);
} // namespace Service::PCTL

View File

@@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/result.h"
namespace Service::PCTL {
constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101};
constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
constexpr Result ResultNoCapability{ErrorModule::PCTL, 131};
constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
} // namespace Service::PCTL

View File

@@ -1,43 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_funcs.h"
namespace Service::PCTL {
enum class Capability : u32 {
None = 0,
Application = 1 << 0,
SnsPost = 1 << 1,
Recovery = 1 << 6,
Status = 1 << 8,
StereoVision = 1 << 9,
System = 1 << 15,
};
DECLARE_ENUM_FLAG_OPERATORS(Capability);
struct ApplicationInfo {
u64 application_id{};
std::array<u8, 32> age_rating{};
u32 parental_control_flag{};
Capability capability{};
};
static_assert(sizeof(ApplicationInfo) == 0x30, "ApplicationInfo has incorrect size.");
// This is nn::pctl::RestrictionSettings
struct RestrictionSettings {
u8 rating_age;
bool sns_post_restriction;
bool free_communication_restriction;
};
static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
// This is nn::pctl::PlayTimerSettings
struct PlayTimerSettings {
std::array<u32, 13> settings;
};
static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
} // namespace Service::PCTL

View File

@@ -46,7 +46,7 @@
#include "core/hle/service/olsc/olsc.h"
#include "core/hle/service/omm/omm.h"
#include "core/hle/service/pcie/pcie.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/pctl/pctl_module.h"
#include "core/hle/service/pcv/pcv.h"
#include "core/hle/service/pm/pm.h"
#include "core/hle/service/prepo/prepo.h"

View File

@@ -43,7 +43,11 @@ void Container::OnTerminate() {
m_is_shut_down = true;
m_layers.ForEachLayer([&](auto& layer) { this->DestroyLayerLocked(layer.GetId()); });
m_layers.ForEachLayer([&](auto& layer) {
if (layer.IsOpen()) {
this->DestroyBufferQueueLocked(&layer);
}
});
m_displays.ForEachDisplay(
[&](auto& display) { m_surface_flinger->RemoveDisplay(display.GetId()); });
@@ -157,29 +161,16 @@ Result Container::CreateLayerLocked(u64* out_layer_id, u64 display_id, u64 owner
auto* const display = m_displays.GetDisplayById(display_id);
R_UNLESS(display != nullptr, VI::ResultNotFound);
s32 consumer_binder_id, producer_binder_id;
m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id);
auto* const layer =
m_layers.CreateLayer(owner_aruid, display, consumer_binder_id, producer_binder_id);
auto* const layer = m_layers.CreateLayer(owner_aruid, display);
R_UNLESS(layer != nullptr, VI::ResultNotFound);
m_surface_flinger->CreateLayer(consumer_binder_id);
*out_layer_id = layer->GetId();
R_SUCCEED();
}
Result Container::DestroyLayerLocked(u64 layer_id) {
auto* const layer = m_layers.GetLayerById(layer_id);
R_UNLESS(layer != nullptr, VI::ResultNotFound);
m_surface_flinger->DestroyLayer(layer->GetConsumerBinderId());
m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(),
layer->GetProducerBinderId());
m_layers.DestroyLayer(layer_id);
R_SUCCEED();
R_SUCCEED_IF(m_layers.DestroyLayer(layer_id));
R_THROW(VI::ResultNotFound);
}
Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid) {
@@ -190,12 +181,7 @@ Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64
R_UNLESS(!layer->IsOpen(), VI::ResultOperationFailed);
R_UNLESS(layer->GetOwnerAruid() == aruid, VI::ResultPermissionDenied);
layer->Open();
if (auto* display = layer->GetDisplay(); display != nullptr) {
m_surface_flinger->AddLayerToDisplayStack(display->GetId(), layer->GetConsumerBinderId());
}
this->CreateBufferQueueLocked(layer);
*out_producer_binder_id = layer->GetProducerBinderId();
R_SUCCEED();
@@ -206,14 +192,30 @@ Result Container::CloseLayerLocked(u64 layer_id) {
R_UNLESS(layer != nullptr, VI::ResultNotFound);
R_UNLESS(layer->IsOpen(), VI::ResultOperationFailed);
this->DestroyBufferQueueLocked(layer);
R_SUCCEED();
}
void Container::CreateBufferQueueLocked(Layer* layer) {
s32 consumer_binder_id, producer_binder_id;
m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id);
layer->Open(consumer_binder_id, producer_binder_id);
if (auto* display = layer->GetDisplay(); display != nullptr) {
m_surface_flinger->AddLayerToDisplayStack(display->GetId(), consumer_binder_id);
}
}
void Container::DestroyBufferQueueLocked(Layer* layer) {
if (auto* display = layer->GetDisplay(); display != nullptr) {
m_surface_flinger->RemoveLayerFromDisplayStack(display->GetId(),
layer->GetConsumerBinderId());
}
layer->Close();
R_SUCCEED();
m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(),
layer->GetProducerBinderId());
}
bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,

View File

@@ -72,6 +72,9 @@ private:
Result OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid);
Result CloseLayerLocked(u64 layer_id);
void CreateBufferQueueLocked(Layer* layer);
void DestroyBufferQueueLocked(Layer* layer);
public:
bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);

View File

@@ -13,31 +13,29 @@ class Layer {
public:
constexpr Layer() = default;
void Initialize(u64 id, u64 owner_aruid, Display* display, s32 consumer_binder_id,
s32 producer_binder_id) {
void Initialize(u64 id, u64 owner_aruid, Display* display) {
m_id = id;
m_owner_aruid = owner_aruid;
m_display = display;
m_consumer_binder_id = consumer_binder_id;
m_producer_binder_id = producer_binder_id;
m_is_initialized = true;
}
void Finalize() {
m_id = {};
m_owner_aruid = {};
m_display = {};
m_consumer_binder_id = {};
m_producer_binder_id = {};
m_is_initialized = {};
}
void Open() {
void Open(s32 consumer_binder_id, s32 producer_binder_id) {
m_consumer_binder_id = consumer_binder_id;
m_producer_binder_id = producer_binder_id;
m_is_open = true;
}
void Close() {
m_is_open = false;
m_producer_binder_id = {};
m_consumer_binder_id = {};
m_is_open = {};
}
u64 GetId() const {

View File

@@ -11,15 +11,13 @@ class LayerList {
public:
constexpr LayerList() = default;
Layer* CreateLayer(u64 owner_aruid, Display* display, s32 consumer_binder_id,
s32 producer_binder_id) {
Layer* CreateLayer(u64 owner_aruid, Display* display) {
Layer* const layer = GetFreeLayer();
if (!layer) {
return nullptr;
}
layer->Initialize(++m_next_id, owner_aruid, display, consumer_binder_id,
producer_binder_id);
layer->Initialize(++m_next_id, owner_aruid, display);
return layer;
}

View File

@@ -285,7 +285,7 @@ void SharedBufferManager::DestroySession(Kernel::KProcess* owner_process) {
auto& session = it->second;
// Destroy the layer.
m_container.DestroyStrayLayer(session.layer_id);
R_ASSERT(m_container.DestroyStrayLayer(session.layer_id));
// Close nvmap handle.
FreeHandle(session.buffer_nvmap_handle, *m_nvdrv, session.nvmap_fd);
@@ -322,6 +322,8 @@ Result SharedBufferManager::GetSharedBufferMemoryHandleId(u64* out_buffer_size,
Result SharedBufferManager::AcquireSharedFrameBuffer(android::Fence* out_fence,
std::array<s32, 4>& out_slot_indexes,
s64* out_target_slot, u64 layer_id) {
std::scoped_lock lk{m_guard};
// Get the producer.
std::shared_ptr<android::BufferQueueProducer> producer;
R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id));
@@ -345,6 +347,8 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence,
Common::Rectangle<s32> crop_region,
u32 transform, s32 swap_interval, u64 layer_id,
s64 slot) {
std::scoped_lock lk{m_guard};
// Get the producer.
std::shared_ptr<android::BufferQueueProducer> producer;
R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id));
@@ -375,6 +379,8 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence,
}
Result SharedBufferManager::CancelSharedFrameBuffer(u64 layer_id, s64 slot) {
std::scoped_lock lk{m_guard};
// Get the producer.
std::shared_ptr<android::BufferQueueProducer> producer;
R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id));
@@ -388,6 +394,8 @@ Result SharedBufferManager::CancelSharedFrameBuffer(u64 layer_id, s64 slot) {
Result SharedBufferManager::GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event,
u64 layer_id) {
std::scoped_lock lk{m_guard};
// Get the producer.
std::shared_ptr<android::BufferQueueProducer> producer;
R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id));

View File

@@ -35,7 +35,7 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R
const s64 min_spacing_critical = device_local_memory - 512_MiB;
const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD);
const s64 min_vacancy_expected = (6 * mem_threshold) / 10;
const s64 min_vacancy_critical = (2 * mem_threshold) / 10;
const s64 min_vacancy_critical = (3 * mem_threshold) / 10;
minimum_memory = static_cast<u64>(
std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected),
DEFAULT_EXPECTED_MEMORY));

View File

@@ -3,7 +3,6 @@
#include "common/common_types.h"
#include "common/math_util.h"
#include "common/settings.h"
#include "video_core/surface.h"
namespace VideoCore::Surface {
@@ -401,20 +400,11 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
}
u64 TranscodedAstcSize(u64 base_size, PixelFormat format) {
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) {
constexpr u64 RGBA8_PIXEL_SIZE = 4;
const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) *
static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE;
const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format);
switch (Settings::values.astc_recompression.GetValue()) {
case Settings::AstcRecompression::Bc1:
return uncompressed_size / 8;
case Settings::AstcRecompression::Bc3:
return uncompressed_size / 4;
default:
return uncompressed_size;
}
return (base_size * base_block_size) / BytesPerBlock(format);
}
} // namespace VideoCore::Surface

View File

@@ -517,6 +517,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format);
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
u64 TranscodedAstcSize(u64 base_size, PixelFormat format);
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format);
} // namespace VideoCore::Surface

View File

@@ -55,7 +55,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
const s64 min_spacing_critical = device_local_memory - 512_MiB;
const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD);
const s64 min_vacancy_expected = (6 * mem_threshold) / 10;
const s64 min_vacancy_critical = (2 * mem_threshold) / 10;
const s64 min_vacancy_critical = (3 * mem_threshold) / 10;
expected_memory = static_cast<u64>(
std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected),
DEFAULT_EXPECTED_MEMORY));
@@ -1979,7 +1979,7 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
if ((IsPixelFormatASTC(image.info.format) &&
True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
True(image.flags & ImageFlagBits::Converted)) {
tentative_size = TranscodedAstcSize(tentative_size, image.info.format);
tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
}
total_used_memory += Common::AlignUp(tentative_size, 1024);
image.lru_index = lru_cache.Insert(image_id, frame_tick);
@@ -2149,7 +2149,7 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
if ((IsPixelFormatASTC(image.info.format) &&
True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
True(image.flags & ImageFlagBits::Converted)) {
tentative_size = TranscodedAstcSize(tentative_size, image.info.format);
tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
}
total_used_memory -= Common::AlignUp(tentative_size, 1024);
const GPUVAddr gpu_addr = image.gpu_addr;

View File

@@ -1604,7 +1604,6 @@ void GMainWindow::ConnectMenuEvents() {
connect_menu(ui->action_Open_yuzu_Folder, &GMainWindow::OnOpenYuzuFolder);
connect_menu(ui->action_Verify_installed_contents, &GMainWindow::OnVerifyInstalledContents);
connect_menu(ui->action_Install_Firmware, &GMainWindow::OnInstallFirmware);
connect_menu(ui->action_Install_Keys, &GMainWindow::OnInstallDecryptionKeys);
connect_menu(ui->action_About, &GMainWindow::OnAbout);
}
@@ -1634,7 +1633,6 @@ void GMainWindow::UpdateMenuState() {
}
ui->action_Install_Firmware->setEnabled(!emulation_running);
ui->action_Install_Keys->setEnabled(!emulation_running);
for (QAction* action : applet_actions) {
action->setEnabled(is_firmware_available && !emulation_running);
@@ -4171,8 +4169,9 @@ void GMainWindow::OnInstallFirmware() {
return;
}
const QString firmware_source_location = QFileDialog::getExistingDirectory(
this, tr("Select Dumped Firmware Source Location"), {}, QFileDialog::ShowDirsOnly);
QString firmware_source_location =
QFileDialog::getExistingDirectory(this, tr("Select Dumped Firmware Source Location"),
QString::fromStdString(""), QFileDialog::ShowDirsOnly);
if (firmware_source_location.isEmpty()) {
return;
}
@@ -4203,9 +4202,8 @@ void GMainWindow::OnInstallFirmware() {
std::vector<std::filesystem::path> out;
const Common::FS::DirEntryCallable callback =
[&out](const std::filesystem::directory_entry& entry) {
if (entry.path().has_extension() && entry.path().extension() == ".nca") {
if (entry.path().has_extension() && entry.path().extension() == ".nca")
out.emplace_back(entry.path());
}
return true;
};
@@ -4237,6 +4235,7 @@ void GMainWindow::OnInstallFirmware() {
auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
bool success = true;
bool cancelled = false;
int i = 0;
for (const auto& firmware_src_path : out) {
i++;
@@ -4251,22 +4250,24 @@ void GMainWindow::OnInstallFirmware() {
success = false;
}
if (QtProgressCallback(
100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
progress.close();
QMessageBox::warning(
this, tr("Firmware install failed"),
tr("Firmware installation cancelled, firmware may be in bad state, "
"restart yuzu or re-install firmware."));
return;
if (QtProgressCallback(100, 20 + (int)(((float)(i) / (float)out.size()) * 70.0))) {
success = false;
cancelled = true;
break;
}
}
if (!success) {
if (!success && !cancelled) {
progress.close();
QMessageBox::critical(this, tr("Firmware install failed"),
tr("One or more firmware files failed to copy into NAND."));
return;
} else if (cancelled) {
progress.close();
QMessageBox::warning(this, tr("Firmware install failed"),
tr("Firmware installation cancelled, firmware may be in bad state, "
"restart yuzu or re-install firmware."));
return;
}
// Re-scan VFS for the newly placed firmware files.
@@ -4294,84 +4295,6 @@ void GMainWindow::OnInstallFirmware() {
OnCheckFirmwareDecryption();
}
void GMainWindow::OnInstallDecryptionKeys() {
// Don't do this while emulation is running.
if (emu_thread != nullptr && emu_thread->IsRunning()) {
return;
}
const QString key_source_location = QFileDialog::getOpenFileName(
this, tr("Select Dumped Keys Location"), {}, QStringLiteral("prod.keys (prod.keys)"), {},
QFileDialog::ReadOnly);
if (key_source_location.isEmpty()) {
return;
}
// Verify that it contains prod.keys, title.keys and optionally, key_retail.bin
LOG_INFO(Frontend, "Installing key files from {}", key_source_location.toStdString());
const std::filesystem::path prod_key_path = key_source_location.toStdString();
const std::filesystem::path key_source_path = prod_key_path.parent_path();
if (!Common::FS::IsDir(key_source_path)) {
return;
}
bool prod_keys_found = false;
std::vector<std::filesystem::path> source_key_files;
if (Common::FS::Exists(prod_key_path)) {
prod_keys_found = true;
source_key_files.emplace_back(prod_key_path);
}
if (Common::FS::Exists(key_source_path / "title.keys")) {
source_key_files.emplace_back(key_source_path / "title.keys");
}
if (Common::FS::Exists(key_source_path / "key_retail.bin")) {
source_key_files.emplace_back(key_source_path / "key_retail.bin");
}
// There should be at least prod.keys.
if (source_key_files.empty() || !prod_keys_found) {
QMessageBox::warning(this, tr("Decryption Keys install failed"),
tr("prod.keys is a required decryption key file."));
return;
}
const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
for (auto key_file : source_key_files) {
std::filesystem::path destination_key_file = yuzu_keys_dir / key_file.filename();
if (!std::filesystem::copy_file(key_file, destination_key_file,
std::filesystem::copy_options::overwrite_existing)) {
LOG_ERROR(Frontend, "Failed to copy file {} to {}", key_file.string(),
destination_key_file.string());
QMessageBox::critical(this, tr("Decryption Keys install failed"),
tr("One or more keys failed to copy."));
return;
}
}
// Reinitialize the key manager, re-read the vfs (for update/dlc files),
// and re-populate the game list in the UI if the user has already added
// game folders.
Core::Crypto::KeyManager::Instance().ReloadKeys();
system->GetFileSystemController().CreateFactories(*vfs);
game_list->PopulateAsync(UISettings::values.game_dirs);
if (ContentManager::AreKeysPresent()) {
QMessageBox::information(this, tr("Decryption Keys install succeeded"),
tr("Decryption Keys were successfully installed"));
} else {
QMessageBox::critical(
this, tr("Decryption Keys install failed"),
tr("Decryption Keys failed to initialize. Check that your dumping tools are "
"up to date and re-dump keys."));
}
OnCheckFirmwareDecryption();
}
void GMainWindow::OnAbout() {
AboutDialog aboutDialog(this);
aboutDialog.exec();

View File

@@ -381,7 +381,6 @@ private slots:
void OnOpenYuzuFolder();
void OnVerifyInstalledContents();
void OnInstallFirmware();
void OnInstallDecryptionKeys();
void OnAbout();
void OnToggleFilterBar();
void OnToggleStatusBar();

View File

@@ -165,9 +165,8 @@
<addaction name="separator"/>
<addaction name="action_Configure_Tas"/>
</widget>
<addaction name="action_Install_Keys"/>
<addaction name="action_Install_Firmware"/>
<addaction name="action_Verify_installed_contents"/>
<addaction name="action_Install_Firmware"/>
<addaction name="separator"/>
<addaction name="menu_cabinet_applet"/>
<addaction name="action_Load_Album"/>
@@ -470,11 +469,6 @@
<string>Install Firmware</string>
</property>
</action>
<action name="action_Install_Keys">
<property name="text">
<string>Install Decryption Keys</string>
</property>
</action>
</widget>
<resources>
<include location="yuzu.qrc"/>