diff options
Diffstat (limited to 'src')
151 files changed, 5489 insertions, 4955 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index 71be2d0b2..0165cb2d1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt | |||
| @@ -24,7 +24,9 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { | |||
| 24 | THEME_MODE("theme_mode"), | 24 | THEME_MODE("theme_mode"), |
| 25 | OVERLAY_SCALE("control_scale"), | 25 | OVERLAY_SCALE("control_scale"), |
| 26 | OVERLAY_OPACITY("control_opacity"), | 26 | OVERLAY_OPACITY("control_opacity"), |
| 27 | LOCK_DRAWER("lock_drawer"); | 27 | LOCK_DRAWER("lock_drawer"), |
| 28 | VERTICAL_ALIGNMENT("vertical_alignment"), | ||
| 29 | FSR_SHARPENING_SLIDER("fsr_sharpening_slider"); | ||
| 28 | 30 | ||
| 29 | override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) | 31 | override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) |
| 30 | 32 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt index fee80bb21..862c6c483 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt | |||
| @@ -93,4 +93,15 @@ object Settings { | |||
| 93 | entries.firstOrNull { it.int == int } ?: Unspecified | 93 | entries.firstOrNull { it.int == int } ?: Unspecified |
| 94 | } | 94 | } |
| 95 | } | 95 | } |
| 96 | |||
| 97 | enum class EmulationVerticalAlignment(val int: Int) { | ||
| 98 | Top(1), | ||
| 99 | Center(0), | ||
| 100 | Bottom(2); | ||
| 101 | |||
| 102 | companion object { | ||
| 103 | fun from(int: Int): EmulationVerticalAlignment = | ||
| 104 | entries.firstOrNull { it.int == int } ?: Center | ||
| 105 | } | ||
| 106 | } | ||
| 96 | } | 107 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 12f7aa1ab..21ca97bc1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt | |||
| @@ -189,6 +189,16 @@ abstract class SettingsItem( | |||
| 189 | ) | 189 | ) |
| 190 | ) | 190 | ) |
| 191 | put( | 191 | put( |
| 192 | SliderSetting( | ||
| 193 | IntSetting.FSR_SHARPENING_SLIDER, | ||
| 194 | R.string.fsr_sharpness, | ||
| 195 | R.string.fsr_sharpness_description, | ||
| 196 | 0, | ||
| 197 | 100, | ||
| 198 | "%" | ||
| 199 | ) | ||
| 200 | ) | ||
| 201 | put( | ||
| 192 | SingleChoiceSetting( | 202 | SingleChoiceSetting( |
| 193 | IntSetting.RENDERER_ANTI_ALIASING, | 203 | IntSetting.RENDERER_ANTI_ALIASING, |
| 194 | R.string.renderer_anti_aliasing, | 204 | R.string.renderer_anti_aliasing, |
| @@ -216,6 +226,15 @@ abstract class SettingsItem( | |||
| 216 | ) | 226 | ) |
| 217 | ) | 227 | ) |
| 218 | put( | 228 | put( |
| 229 | SingleChoiceSetting( | ||
| 230 | IntSetting.VERTICAL_ALIGNMENT, | ||
| 231 | R.string.vertical_alignment, | ||
| 232 | 0, | ||
| 233 | R.array.verticalAlignmentEntries, | ||
| 234 | R.array.verticalAlignmentValues | ||
| 235 | ) | ||
| 236 | ) | ||
| 237 | put( | ||
| 219 | SwitchSetting( | 238 | SwitchSetting( |
| 220 | BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE, | 239 | BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE, |
| 221 | R.string.use_disk_shader_cache, | 240 | R.string.use_disk_shader_cache, |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 2ad2f4966..db1a58147 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt | |||
| @@ -143,10 +143,12 @@ class SettingsFragmentPresenter( | |||
| 143 | add(IntSetting.RENDERER_RESOLUTION.key) | 143 | add(IntSetting.RENDERER_RESOLUTION.key) |
| 144 | add(IntSetting.RENDERER_VSYNC.key) | 144 | add(IntSetting.RENDERER_VSYNC.key) |
| 145 | add(IntSetting.RENDERER_SCALING_FILTER.key) | 145 | add(IntSetting.RENDERER_SCALING_FILTER.key) |
| 146 | add(IntSetting.FSR_SHARPENING_SLIDER.key) | ||
| 146 | add(IntSetting.RENDERER_ANTI_ALIASING.key) | 147 | add(IntSetting.RENDERER_ANTI_ALIASING.key) |
| 147 | add(IntSetting.MAX_ANISOTROPY.key) | 148 | add(IntSetting.MAX_ANISOTROPY.key) |
| 148 | add(IntSetting.RENDERER_SCREEN_LAYOUT.key) | 149 | add(IntSetting.RENDERER_SCREEN_LAYOUT.key) |
| 149 | add(IntSetting.RENDERER_ASPECT_RATIO.key) | 150 | add(IntSetting.RENDERER_ASPECT_RATIO.key) |
| 151 | add(IntSetting.VERTICAL_ALIGNMENT.key) | ||
| 150 | add(BooleanSetting.PICTURE_IN_PICTURE.key) | 152 | add(BooleanSetting.PICTURE_IN_PICTURE.key) |
| 151 | add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key) | 153 | add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key) |
| 152 | add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key) | 154 | add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key) |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt index f5647fa95..872553ac4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt | |||
| @@ -104,7 +104,10 @@ class AddonsFragment : Fragment() { | |||
| 104 | requireActivity(), | 104 | requireActivity(), |
| 105 | titleId = R.string.addon_notice, | 105 | titleId = R.string.addon_notice, |
| 106 | descriptionId = R.string.addon_notice_description, | 106 | descriptionId = R.string.addon_notice_description, |
| 107 | positiveAction = { addonViewModel.showModInstallPicker(true) } | 107 | dismissible = false, |
| 108 | positiveAction = { addonViewModel.showModInstallPicker(true) }, | ||
| 109 | negativeAction = {}, | ||
| 110 | negativeButtonTitleId = R.string.close | ||
| 108 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | 111 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 109 | addonViewModel.showModNoticeDialog(false) | 112 | addonViewModel.showModNoticeDialog(false) |
| 110 | } | 113 | } |
| @@ -119,7 +122,8 @@ class AddonsFragment : Fragment() { | |||
| 119 | requireActivity(), | 122 | requireActivity(), |
| 120 | titleId = R.string.confirm_uninstall, | 123 | titleId = R.string.confirm_uninstall, |
| 121 | descriptionId = R.string.confirm_uninstall_description, | 124 | descriptionId = R.string.confirm_uninstall_description, |
| 122 | positiveAction = { addonViewModel.onDeleteAddon(it) } | 125 | positiveAction = { addonViewModel.onDeleteAddon(it) }, |
| 126 | negativeAction = {} | ||
| 123 | ).show(parentFragmentManager, MessageDialogFragment.TAG) | 127 | ).show(parentFragmentManager, MessageDialogFragment.TAG) |
| 124 | addonViewModel.setAddonToDelete(null) | 128 | addonViewModel.setAddonToDelete(null) |
| 125 | } | 129 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 44af896da..6b25cc525 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt | |||
| @@ -15,7 +15,9 @@ import android.os.Handler | |||
| 15 | import android.os.Looper | 15 | import android.os.Looper |
| 16 | import android.os.PowerManager | 16 | import android.os.PowerManager |
| 17 | import android.os.SystemClock | 17 | import android.os.SystemClock |
| 18 | import android.util.Rational | ||
| 18 | import android.view.* | 19 | import android.view.* |
| 20 | import android.widget.FrameLayout | ||
| 19 | import android.widget.TextView | 21 | import android.widget.TextView |
| 20 | import android.widget.Toast | 22 | import android.widget.Toast |
| 21 | import androidx.activity.OnBackPressedCallback | 23 | import androidx.activity.OnBackPressedCallback |
| @@ -24,6 +26,7 @@ import androidx.core.content.res.ResourcesCompat | |||
| 24 | import androidx.core.graphics.Insets | 26 | import androidx.core.graphics.Insets |
| 25 | import androidx.core.view.ViewCompat | 27 | import androidx.core.view.ViewCompat |
| 26 | import androidx.core.view.WindowInsetsCompat | 28 | import androidx.core.view.WindowInsetsCompat |
| 29 | import androidx.core.view.updateLayoutParams | ||
| 27 | import androidx.core.view.updatePadding | 30 | import androidx.core.view.updatePadding |
| 28 | import androidx.drawerlayout.widget.DrawerLayout | 31 | import androidx.drawerlayout.widget.DrawerLayout |
| 29 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener | 32 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener |
| @@ -52,6 +55,7 @@ import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting | |||
| 52 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting | 55 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting |
| 53 | import org.yuzu.yuzu_emu.features.settings.model.Settings | 56 | import org.yuzu.yuzu_emu.features.settings.model.Settings |
| 54 | import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation | 57 | import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation |
| 58 | import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationVerticalAlignment | ||
| 55 | import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile | 59 | import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile |
| 56 | import org.yuzu.yuzu_emu.model.DriverViewModel | 60 | import org.yuzu.yuzu_emu.model.DriverViewModel |
| 57 | import org.yuzu.yuzu_emu.model.Game | 61 | import org.yuzu.yuzu_emu.model.Game |
| @@ -617,7 +621,46 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 617 | } | 621 | } |
| 618 | 622 | ||
| 619 | private fun updateScreenLayout() { | 623 | private fun updateScreenLayout() { |
| 620 | binding.surfaceEmulation.setAspectRatio(null) | 624 | val verticalAlignment = |
| 625 | EmulationVerticalAlignment.from(IntSetting.VERTICAL_ALIGNMENT.getInt()) | ||
| 626 | val aspectRatio = when (IntSetting.RENDERER_ASPECT_RATIO.getInt()) { | ||
| 627 | 0 -> Rational(16, 9) | ||
| 628 | 1 -> Rational(4, 3) | ||
| 629 | 2 -> Rational(21, 9) | ||
| 630 | 3 -> Rational(16, 10) | ||
| 631 | else -> null // Best fit | ||
| 632 | } | ||
| 633 | when (verticalAlignment) { | ||
| 634 | EmulationVerticalAlignment.Top -> { | ||
| 635 | binding.surfaceEmulation.setAspectRatio(aspectRatio) | ||
| 636 | val params = FrameLayout.LayoutParams( | ||
| 637 | ViewGroup.LayoutParams.MATCH_PARENT, | ||
| 638 | ViewGroup.LayoutParams.WRAP_CONTENT | ||
| 639 | ) | ||
| 640 | params.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL | ||
| 641 | binding.surfaceEmulation.layoutParams = params | ||
| 642 | } | ||
| 643 | |||
| 644 | EmulationVerticalAlignment.Center -> { | ||
| 645 | binding.surfaceEmulation.setAspectRatio(null) | ||
| 646 | binding.surfaceEmulation.updateLayoutParams { | ||
| 647 | width = ViewGroup.LayoutParams.MATCH_PARENT | ||
| 648 | height = ViewGroup.LayoutParams.MATCH_PARENT | ||
| 649 | } | ||
| 650 | } | ||
| 651 | |||
| 652 | EmulationVerticalAlignment.Bottom -> { | ||
| 653 | binding.surfaceEmulation.setAspectRatio(aspectRatio) | ||
| 654 | val params = | ||
| 655 | FrameLayout.LayoutParams( | ||
| 656 | ViewGroup.LayoutParams.MATCH_PARENT, | ||
| 657 | ViewGroup.LayoutParams.WRAP_CONTENT | ||
| 658 | ) | ||
| 659 | params.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL | ||
| 660 | binding.surfaceEmulation.layoutParams = params | ||
| 661 | } | ||
| 662 | } | ||
| 663 | emulationState.updateSurface() | ||
| 621 | emulationActivity?.buildPictureInPictureParams() | 664 | emulationActivity?.buildPictureInPictureParams() |
| 622 | updateOrientation() | 665 | updateOrientation() |
| 623 | } | 666 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt index d14b2c634..3ea5e16ca 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt | |||
| @@ -243,7 +243,9 @@ class GamePropertiesFragment : Fragment() { | |||
| 243 | requireActivity(), | 243 | requireActivity(), |
| 244 | titleId = R.string.delete_save_data, | 244 | titleId = R.string.delete_save_data, |
| 245 | descriptionId = R.string.delete_save_data_warning_description, | 245 | descriptionId = R.string.delete_save_data_warning_description, |
| 246 | positiveAction = { | 246 | positiveButtonTitleId = android.R.string.cancel, |
| 247 | negativeButtonTitleId = android.R.string.ok, | ||
| 248 | negativeAction = { | ||
| 247 | File(args.game.saveDir).deleteRecursively() | 249 | File(args.game.saveDir).deleteRecursively() |
| 248 | Toast.makeText( | 250 | Toast.makeText( |
| 249 | YuzuApplication.appContext, | 251 | YuzuApplication.appContext, |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt index 22b084b9a..c370964e1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/MessageDialogFragment.kt | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | package org.yuzu.yuzu_emu.fragments | 4 | package org.yuzu.yuzu_emu.fragments |
| 5 | 5 | ||
| 6 | import android.app.Dialog | 6 | import android.app.Dialog |
| 7 | import android.content.DialogInterface | ||
| 8 | import android.content.Intent | 7 | import android.content.Intent |
| 9 | import android.net.Uri | 8 | import android.net.Uri |
| 10 | import android.os.Bundle | 9 | import android.os.Bundle |
| @@ -16,18 +15,52 @@ import androidx.lifecycle.ViewModelProvider | |||
| 16 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 15 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 17 | import org.yuzu.yuzu_emu.R | 16 | import org.yuzu.yuzu_emu.R |
| 18 | import org.yuzu.yuzu_emu.model.MessageDialogViewModel | 17 | import org.yuzu.yuzu_emu.model.MessageDialogViewModel |
| 18 | import org.yuzu.yuzu_emu.utils.Log | ||
| 19 | 19 | ||
| 20 | class MessageDialogFragment : DialogFragment() { | 20 | class MessageDialogFragment : DialogFragment() { |
| 21 | private val messageDialogViewModel: MessageDialogViewModel by activityViewModels() | 21 | private val messageDialogViewModel: MessageDialogViewModel by activityViewModels() |
| 22 | 22 | ||
| 23 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | 23 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { |
| 24 | val titleId = requireArguments().getInt(TITLE_ID) | 24 | val titleId = requireArguments().getInt(TITLE_ID) |
| 25 | val titleString = requireArguments().getString(TITLE_STRING)!! | 25 | val title = if (titleId != 0) { |
| 26 | getString(titleId) | ||
| 27 | } else { | ||
| 28 | requireArguments().getString(TITLE_STRING)!! | ||
| 29 | } | ||
| 30 | |||
| 26 | val descriptionId = requireArguments().getInt(DESCRIPTION_ID) | 31 | val descriptionId = requireArguments().getInt(DESCRIPTION_ID) |
| 27 | val descriptionString = requireArguments().getString(DESCRIPTION_STRING)!! | 32 | val description = if (descriptionId != 0) { |
| 33 | getString(descriptionId) | ||
| 34 | } else { | ||
| 35 | requireArguments().getString(DESCRIPTION_STRING)!! | ||
| 36 | } | ||
| 37 | |||
| 38 | val positiveButtonId = requireArguments().getInt(POSITIVE_BUTTON_TITLE_ID) | ||
| 39 | val positiveButtonString = requireArguments().getString(POSITIVE_BUTTON_TITLE_STRING)!! | ||
| 40 | val positiveButton = if (positiveButtonId != 0) { | ||
| 41 | getString(positiveButtonId) | ||
| 42 | } else if (positiveButtonString.isNotEmpty()) { | ||
| 43 | positiveButtonString | ||
| 44 | } else if (messageDialogViewModel.positiveAction != null) { | ||
| 45 | getString(android.R.string.ok) | ||
| 46 | } else { | ||
| 47 | getString(R.string.close) | ||
| 48 | } | ||
| 49 | |||
| 50 | val negativeButtonId = requireArguments().getInt(NEGATIVE_BUTTON_TITLE_ID) | ||
| 51 | val negativeButtonString = requireArguments().getString(NEGATIVE_BUTTON_TITLE_STRING)!! | ||
| 52 | val negativeButton = if (negativeButtonId != 0) { | ||
| 53 | getString(negativeButtonId) | ||
| 54 | } else if (negativeButtonString.isNotEmpty()) { | ||
| 55 | negativeButtonString | ||
| 56 | } else { | ||
| 57 | getString(android.R.string.cancel) | ||
| 58 | } | ||
| 59 | |||
| 28 | val helpLinkId = requireArguments().getInt(HELP_LINK) | 60 | val helpLinkId = requireArguments().getInt(HELP_LINK) |
| 29 | val dismissible = requireArguments().getBoolean(DISMISSIBLE) | 61 | val dismissible = requireArguments().getBoolean(DISMISSIBLE) |
| 30 | val clearPositiveAction = requireArguments().getBoolean(CLEAR_POSITIVE_ACTION) | 62 | val clearPositiveAction = requireArguments().getBoolean(CLEAR_ACTIONS) |
| 63 | val showNegativeButton = requireArguments().getBoolean(SHOW_NEGATIVE_BUTTON) | ||
| 31 | 64 | ||
| 32 | val builder = MaterialAlertDialogBuilder(requireContext()) | 65 | val builder = MaterialAlertDialogBuilder(requireContext()) |
| 33 | 66 | ||
| @@ -35,21 +68,19 @@ class MessageDialogFragment : DialogFragment() { | |||
| 35 | messageDialogViewModel.positiveAction = null | 68 | messageDialogViewModel.positiveAction = null |
| 36 | } | 69 | } |
| 37 | 70 | ||
| 38 | if (messageDialogViewModel.positiveAction == null) { | 71 | builder.setPositiveButton(positiveButton) { _, _ -> |
| 39 | builder.setPositiveButton(R.string.close, null) | 72 | messageDialogViewModel.positiveAction?.invoke() |
| 40 | } else { | 73 | } |
| 41 | builder.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> | 74 | if (messageDialogViewModel.negativeAction != null || showNegativeButton) { |
| 42 | messageDialogViewModel.positiveAction?.invoke() | 75 | builder.setNegativeButton(negativeButton) { _, _ -> |
| 43 | }.setNegativeButton(android.R.string.cancel, null) | 76 | messageDialogViewModel.negativeAction?.invoke() |
| 77 | } | ||
| 44 | } | 78 | } |
| 45 | 79 | ||
| 46 | if (titleId != 0) builder.setTitle(titleId) | 80 | if (title.isNotEmpty()) builder.setTitle(title) |
| 47 | if (titleString.isNotEmpty()) builder.setTitle(titleString) | 81 | if (description.isNotEmpty()) { |
| 48 | 82 | builder.setMessage(Html.fromHtml(description, Html.FROM_HTML_MODE_LEGACY)) | |
| 49 | if (descriptionId != 0) { | ||
| 50 | builder.setMessage(Html.fromHtml(getString(descriptionId), Html.FROM_HTML_MODE_LEGACY)) | ||
| 51 | } | 83 | } |
| 52 | if (descriptionString.isNotEmpty()) builder.setMessage(descriptionString) | ||
| 53 | 84 | ||
| 54 | if (helpLinkId != 0) { | 85 | if (helpLinkId != 0) { |
| 55 | builder.setNeutralButton(R.string.learn_more) { _, _ -> | 86 | builder.setNeutralButton(R.string.learn_more) { _, _ -> |
| @@ -76,8 +107,41 @@ class MessageDialogFragment : DialogFragment() { | |||
| 76 | private const val DESCRIPTION_STRING = "DescriptionString" | 107 | private const val DESCRIPTION_STRING = "DescriptionString" |
| 77 | private const val HELP_LINK = "Link" | 108 | private const val HELP_LINK = "Link" |
| 78 | private const val DISMISSIBLE = "Dismissible" | 109 | private const val DISMISSIBLE = "Dismissible" |
| 79 | private const val CLEAR_POSITIVE_ACTION = "ClearPositiveAction" | 110 | private const val CLEAR_ACTIONS = "ClearActions" |
| 80 | 111 | private const val POSITIVE_BUTTON_TITLE_ID = "PositiveButtonTitleId" | |
| 112 | private const val POSITIVE_BUTTON_TITLE_STRING = "PositiveButtonTitleString" | ||
| 113 | private const val SHOW_NEGATIVE_BUTTON = "ShowNegativeButton" | ||
| 114 | private const val NEGATIVE_BUTTON_TITLE_ID = "NegativeButtonTitleId" | ||
| 115 | private const val NEGATIVE_BUTTON_TITLE_STRING = "NegativeButtonTitleString" | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Creates a new [MessageDialogFragment] instance. | ||
| 119 | * @param activity Activity that will hold a [MessageDialogViewModel] instance if using | ||
| 120 | * [positiveAction] or [negativeAction]. | ||
| 121 | * @param titleId String resource ID that will be used for the title. [titleString] used if 0. | ||
| 122 | * @param titleString String that will be used for the title. No title is set if empty. | ||
| 123 | * @param descriptionId String resource ID that will be used for the description. | ||
| 124 | * [descriptionString] used if 0. | ||
| 125 | * @param descriptionString String that will be used for the description. | ||
| 126 | * No description is set if empty. | ||
| 127 | * @param helpLinkId String resource ID that contains a help link. Will be added as a neutral | ||
| 128 | * button with the title R.string.help. | ||
| 129 | * @param dismissible Whether the dialog is dismissible or not. Typically used to ensure that | ||
| 130 | * the user clicks on one of the dialog buttons before closing. | ||
| 131 | * @param positiveButtonTitleId String resource ID that will be used for the positive button. | ||
| 132 | * [positiveButtonTitleString] used if 0. | ||
| 133 | * @param positiveButtonTitleString String that will be used for the positive button. | ||
| 134 | * android.R.string.close used if empty. android.R.string.ok will be used if [positiveAction] | ||
| 135 | * is not null. | ||
| 136 | * @param positiveAction Lambda to run when the positive button is clicked. | ||
| 137 | * @param showNegativeButton Normally the negative button isn't shown if there is no | ||
| 138 | * [negativeAction] set. This can override that behavior to always show a button. | ||
| 139 | * @param negativeButtonTitleId String resource ID that will be used for the negative button. | ||
| 140 | * [negativeButtonTitleString] used if 0. | ||
| 141 | * @param negativeButtonTitleString String that will be used for the negative button. | ||
| 142 | * android.R.string.cancel used if empty. | ||
| 143 | * @param negativeAction Lambda to run when the negative button is clicked | ||
| 144 | */ | ||
| 81 | fun newInstance( | 145 | fun newInstance( |
| 82 | activity: FragmentActivity? = null, | 146 | activity: FragmentActivity? = null, |
| 83 | titleId: Int = 0, | 147 | titleId: Int = 0, |
| @@ -86,16 +150,27 @@ class MessageDialogFragment : DialogFragment() { | |||
| 86 | descriptionString: String = "", | 150 | descriptionString: String = "", |
| 87 | helpLinkId: Int = 0, | 151 | helpLinkId: Int = 0, |
| 88 | dismissible: Boolean = true, | 152 | dismissible: Boolean = true, |
| 89 | positiveAction: (() -> Unit)? = null | 153 | positiveButtonTitleId: Int = 0, |
| 154 | positiveButtonTitleString: String = "", | ||
| 155 | positiveAction: (() -> Unit)? = null, | ||
| 156 | showNegativeButton: Boolean = false, | ||
| 157 | negativeButtonTitleId: Int = 0, | ||
| 158 | negativeButtonTitleString: String = "", | ||
| 159 | negativeAction: (() -> Unit)? = null | ||
| 90 | ): MessageDialogFragment { | 160 | ): MessageDialogFragment { |
| 91 | var clearPositiveAction = false | 161 | var clearActions = false |
| 92 | if (activity != null) { | 162 | if (activity != null) { |
| 93 | ViewModelProvider(activity)[MessageDialogViewModel::class.java].apply { | 163 | ViewModelProvider(activity)[MessageDialogViewModel::class.java].apply { |
| 94 | clear() | 164 | clear() |
| 95 | this.positiveAction = positiveAction | 165 | this.positiveAction = positiveAction |
| 166 | this.negativeAction = negativeAction | ||
| 96 | } | 167 | } |
| 97 | } else { | 168 | } else { |
| 98 | clearPositiveAction = true | 169 | clearActions = true |
| 170 | } | ||
| 171 | |||
| 172 | if (activity == null && (positiveAction == null || negativeAction == null)) { | ||
| 173 | Log.warning("[$TAG] Tried to set action with no activity!") | ||
| 99 | } | 174 | } |
| 100 | 175 | ||
| 101 | val dialog = MessageDialogFragment() | 176 | val dialog = MessageDialogFragment() |
| @@ -106,7 +181,12 @@ class MessageDialogFragment : DialogFragment() { | |||
| 106 | putString(DESCRIPTION_STRING, descriptionString) | 181 | putString(DESCRIPTION_STRING, descriptionString) |
| 107 | putInt(HELP_LINK, helpLinkId) | 182 | putInt(HELP_LINK, helpLinkId) |
| 108 | putBoolean(DISMISSIBLE, dismissible) | 183 | putBoolean(DISMISSIBLE, dismissible) |
| 109 | putBoolean(CLEAR_POSITIVE_ACTION, clearPositiveAction) | 184 | putBoolean(CLEAR_ACTIONS, clearActions) |
| 185 | putInt(POSITIVE_BUTTON_TITLE_ID, positiveButtonTitleId) | ||
| 186 | putString(POSITIVE_BUTTON_TITLE_STRING, positiveButtonTitleString) | ||
| 187 | putBoolean(SHOW_NEGATIVE_BUTTON, showNegativeButton) | ||
| 188 | putInt(NEGATIVE_BUTTON_TITLE_ID, negativeButtonTitleId) | ||
| 189 | putString(NEGATIVE_BUTTON_TITLE_STRING, negativeButtonTitleString) | ||
| 110 | } | 190 | } |
| 111 | dialog.arguments = bundle | 191 | dialog.arguments = bundle |
| 112 | return dialog | 192 | return dialog |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/MessageDialogViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/MessageDialogViewModel.kt index 641c5cb17..2db005e49 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/MessageDialogViewModel.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/MessageDialogViewModel.kt | |||
| @@ -7,8 +7,10 @@ import androidx.lifecycle.ViewModel | |||
| 7 | 7 | ||
| 8 | class MessageDialogViewModel : ViewModel() { | 8 | class MessageDialogViewModel : ViewModel() { |
| 9 | var positiveAction: (() -> Unit)? = null | 9 | var positiveAction: (() -> Unit)? = null |
| 10 | var negativeAction: (() -> Unit)? = null | ||
| 10 | 11 | ||
| 11 | fun clear() { | 12 | fun clear() { |
| 12 | positiveAction = null | 13 | positiveAction = null |
| 14 | negativeAction = null | ||
| 13 | } | 15 | } |
| 14 | } | 16 | } |
diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index 4a3bc8e53..00baf86a9 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h | |||
| @@ -38,6 +38,13 @@ struct Values { | |||
| 38 | Settings::Specialization::Default, | 38 | Settings::Specialization::Default, |
| 39 | true, | 39 | true, |
| 40 | true}; | 40 | true}; |
| 41 | Settings::Setting<s32> vertical_alignment{linkage, | ||
| 42 | 0, | ||
| 43 | "vertical_alignment", | ||
| 44 | Settings::Category::Android, | ||
| 45 | Settings::Specialization::Default, | ||
| 46 | true, | ||
| 47 | true}; | ||
| 41 | 48 | ||
| 42 | Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path", | 49 | Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path", |
| 43 | Settings::Category::GpuDriver}; | 50 | Settings::Category::GpuDriver}; |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 4acc60956..a4d8454e8 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -49,9 +49,7 @@ | |||
| 49 | #include "core/frontend/applets/profile_select.h" | 49 | #include "core/frontend/applets/profile_select.h" |
| 50 | #include "core/frontend/applets/software_keyboard.h" | 50 | #include "core/frontend/applets/software_keyboard.h" |
| 51 | #include "core/frontend/applets/web_browser.h" | 51 | #include "core/frontend/applets/web_browser.h" |
| 52 | #include "core/hle/service/am/applet_ae.h" | ||
| 53 | #include "core/hle/service/am/applet_manager.h" | 52 | #include "core/hle/service/am/applet_manager.h" |
| 54 | #include "core/hle/service/am/applet_oe.h" | ||
| 55 | #include "core/hle/service/am/frontend/applets.h" | 53 | #include "core/hle/service/am/frontend/applets.h" |
| 56 | #include "core/hle/service/filesystem/filesystem.h" | 54 | #include "core/hle/service/filesystem/filesystem.h" |
| 57 | #include "core/loader/loader.h" | 55 | #include "core/loader/loader.h" |
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 4701913eb..1bd6455b4 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml | |||
| @@ -292,4 +292,15 @@ | |||
| 292 | <item>5</item> | 292 | <item>5</item> |
| 293 | </integer-array> | 293 | </integer-array> |
| 294 | 294 | ||
| 295 | <string-array name="verticalAlignmentEntries"> | ||
| 296 | <item>@string/top</item> | ||
| 297 | <item>@string/center</item> | ||
| 298 | <item>@string/bottom</item> | ||
| 299 | </string-array> | ||
| 300 | <integer-array name="verticalAlignmentValues"> | ||
| 301 | <item>1</item> | ||
| 302 | <item>0</item> | ||
| 303 | <item>2</item> | ||
| 304 | </integer-array> | ||
| 305 | |||
| 295 | </resources> | 306 | </resources> |
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 489e00107..78a4c958a 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -226,6 +226,8 @@ | |||
| 226 | <string name="renderer_screen_layout">Orientation</string> | 226 | <string name="renderer_screen_layout">Orientation</string> |
| 227 | <string name="renderer_aspect_ratio">Aspect ratio</string> | 227 | <string name="renderer_aspect_ratio">Aspect ratio</string> |
| 228 | <string name="renderer_scaling_filter">Window adapting filter</string> | 228 | <string name="renderer_scaling_filter">Window adapting filter</string> |
| 229 | <string name="fsr_sharpness">FSR sharpness</string> | ||
| 230 | <string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string> | ||
| 229 | <string name="renderer_anti_aliasing">Anti-aliasing method</string> | 231 | <string name="renderer_anti_aliasing">Anti-aliasing method</string> |
| 230 | <string name="renderer_force_max_clock">Force maximum clocks (Adreno only)</string> | 232 | <string name="renderer_force_max_clock">Force maximum clocks (Adreno only)</string> |
| 231 | <string name="renderer_force_max_clock_description">Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).</string> | 233 | <string name="renderer_force_max_clock_description">Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).</string> |
| @@ -558,6 +560,12 @@ | |||
| 558 | <string name="mute">Mute</string> | 560 | <string name="mute">Mute</string> |
| 559 | <string name="unmute">Unmute</string> | 561 | <string name="unmute">Unmute</string> |
| 560 | 562 | ||
| 563 | <!-- Emulation vertical alignment --> | ||
| 564 | <string name="vertical_alignment">Vertical alignment</string> | ||
| 565 | <string name="top">Top</string> | ||
| 566 | <string name="center">Center</string> | ||
| 567 | <string name="bottom">Bottom</string> | ||
| 568 | |||
| 561 | <!-- Licenses screen strings --> | 569 | <!-- Licenses screen strings --> |
| 562 | <string name="licenses">Licenses</string> | 570 | <string name="licenses">Licenses</string> |
| 563 | <string name="license_fidelityfx_fsr" translatable="false">FidelityFX-FSR</string> | 571 | <string name="license_fidelityfx_fsr" translatable="false">FidelityFX-FSR</string> |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 33838ac2f..bc7f95fea 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -417,74 +417,72 @@ add_library(core STATIC | |||
| 417 | hle/service/am/am_types.h | 417 | hle/service/am/am_types.h |
| 418 | hle/service/am/applet.cpp | 418 | hle/service/am/applet.cpp |
| 419 | hle/service/am/applet.h | 419 | hle/service/am/applet.h |
| 420 | hle/service/am/applet_ae.cpp | ||
| 421 | hle/service/am/applet_ae.h | ||
| 422 | hle/service/am/applet_manager.cpp | 420 | hle/service/am/applet_manager.cpp |
| 423 | hle/service/am/applet_data_broker.cpp | 421 | hle/service/am/applet_data_broker.cpp |
| 424 | hle/service/am/applet_data_broker.h | 422 | hle/service/am/applet_data_broker.h |
| 425 | hle/service/am/applet_manager.h | 423 | hle/service/am/applet_manager.h |
| 426 | hle/service/am/applet_oe.cpp | ||
| 427 | hle/service/am/applet_oe.h | ||
| 428 | hle/service/am/applet_common_functions.cpp | ||
| 429 | hle/service/am/applet_common_functions.h | ||
| 430 | hle/service/am/applet_message_queue.cpp | 424 | hle/service/am/applet_message_queue.cpp |
| 431 | hle/service/am/applet_message_queue.h | 425 | hle/service/am/applet_message_queue.h |
| 432 | hle/service/am/application_creator.cpp | ||
| 433 | hle/service/am/application_creator.h | ||
| 434 | hle/service/am/application_functions.cpp | ||
| 435 | hle/service/am/application_functions.h | ||
| 436 | hle/service/am/application_proxy.cpp | ||
| 437 | hle/service/am/application_proxy.h | ||
| 438 | hle/service/am/audio_controller.cpp | ||
| 439 | hle/service/am/audio_controller.h | ||
| 440 | hle/service/am/common_state_getter.cpp | ||
| 441 | hle/service/am/common_state_getter.h | ||
| 442 | hle/service/am/debug_functions.cpp | ||
| 443 | hle/service/am/debug_functions.h | ||
| 444 | hle/service/am/display_controller.cpp | ||
| 445 | hle/service/am/display_controller.h | ||
| 446 | hle/service/am/global_state_controller.cpp | ||
| 447 | hle/service/am/global_state_controller.h | ||
| 448 | hle/service/am/hid_registration.cpp | 426 | hle/service/am/hid_registration.cpp |
| 449 | hle/service/am/hid_registration.h | 427 | hle/service/am/hid_registration.h |
| 450 | hle/service/am/home_menu_functions.cpp | ||
| 451 | hle/service/am/home_menu_functions.h | ||
| 452 | hle/service/am/idle.cpp | ||
| 453 | hle/service/am/idle.h | ||
| 454 | hle/service/am/library_applet_accessor.cpp | ||
| 455 | hle/service/am/library_applet_accessor.h | ||
| 456 | hle/service/am/library_applet_creator.cpp | ||
| 457 | hle/service/am/library_applet_creator.h | ||
| 458 | hle/service/am/library_applet_proxy.cpp | ||
| 459 | hle/service/am/library_applet_proxy.h | ||
| 460 | hle/service/am/library_applet_self_accessor.cpp | ||
| 461 | hle/service/am/library_applet_self_accessor.h | ||
| 462 | hle/service/am/library_applet_storage.cpp | 428 | hle/service/am/library_applet_storage.cpp |
| 463 | hle/service/am/library_applet_storage.h | 429 | hle/service/am/library_applet_storage.h |
| 464 | hle/service/am/lock_accessor.cpp | ||
| 465 | hle/service/am/lock_accessor.h | ||
| 466 | hle/service/am/managed_layer_holder.cpp | 430 | hle/service/am/managed_layer_holder.cpp |
| 467 | hle/service/am/managed_layer_holder.h | 431 | hle/service/am/managed_layer_holder.h |
| 468 | hle/service/am/omm.cpp | ||
| 469 | hle/service/am/omm.h | ||
| 470 | hle/service/am/process_winding_controller.cpp | ||
| 471 | hle/service/am/process_winding_controller.h | ||
| 472 | hle/service/am/process.cpp | 432 | hle/service/am/process.cpp |
| 473 | hle/service/am/process.h | 433 | hle/service/am/process.h |
| 474 | hle/service/am/self_controller.cpp | 434 | hle/service/am/service/all_system_applet_proxies_service.cpp |
| 475 | hle/service/am/self_controller.h | 435 | hle/service/am/service/all_system_applet_proxies_service.h |
| 476 | hle/service/am/system_applet_proxy.cpp | 436 | hle/service/am/service/applet_common_functions.cpp |
| 477 | hle/service/am/system_applet_proxy.h | 437 | hle/service/am/service/applet_common_functions.h |
| 438 | hle/service/am/service/application_accessor.cpp | ||
| 439 | hle/service/am/service/application_accessor.h | ||
| 440 | hle/service/am/service/application_creator.cpp | ||
| 441 | hle/service/am/service/application_creator.h | ||
| 442 | hle/service/am/service/application_functions.cpp | ||
| 443 | hle/service/am/service/application_functions.h | ||
| 444 | hle/service/am/service/application_proxy_service.cpp | ||
| 445 | hle/service/am/service/application_proxy_service.h | ||
| 446 | hle/service/am/service/application_proxy.cpp | ||
| 447 | hle/service/am/service/application_proxy.h | ||
| 448 | hle/service/am/service/audio_controller.cpp | ||
| 449 | hle/service/am/service/audio_controller.h | ||
| 450 | hle/service/am/service/common_state_getter.cpp | ||
| 451 | hle/service/am/service/common_state_getter.h | ||
| 452 | hle/service/am/service/cradle_firmware_updater.cpp | ||
| 453 | hle/service/am/service/cradle_firmware_updater.h | ||
| 454 | hle/service/am/service/debug_functions.cpp | ||
| 455 | hle/service/am/service/debug_functions.h | ||
| 456 | hle/service/am/service/display_controller.cpp | ||
| 457 | hle/service/am/service/display_controller.h | ||
| 458 | hle/service/am/service/global_state_controller.cpp | ||
| 459 | hle/service/am/service/global_state_controller.h | ||
| 460 | hle/service/am/service/home_menu_functions.cpp | ||
| 461 | hle/service/am/service/home_menu_functions.h | ||
| 462 | hle/service/am/service/library_applet_accessor.cpp | ||
| 463 | hle/service/am/service/library_applet_accessor.h | ||
| 464 | hle/service/am/service/library_applet_creator.cpp | ||
| 465 | hle/service/am/service/library_applet_creator.h | ||
| 466 | hle/service/am/service/library_applet_proxy.cpp | ||
| 467 | hle/service/am/service/library_applet_proxy.h | ||
| 468 | hle/service/am/service/library_applet_self_accessor.cpp | ||
| 469 | hle/service/am/service/library_applet_self_accessor.h | ||
| 470 | hle/service/am/service/lock_accessor.cpp | ||
| 471 | hle/service/am/service/lock_accessor.h | ||
| 472 | hle/service/am/service/process_winding_controller.cpp | ||
| 473 | hle/service/am/service/process_winding_controller.h | ||
| 474 | hle/service/am/service/self_controller.cpp | ||
| 475 | hle/service/am/service/self_controller.h | ||
| 476 | hle/service/am/service/storage_accessor.cpp | ||
| 477 | hle/service/am/service/storage_accessor.h | ||
| 478 | hle/service/am/service/storage.cpp | ||
| 479 | hle/service/am/service/storage.h | ||
| 480 | hle/service/am/service/system_applet_proxy.cpp | ||
| 481 | hle/service/am/service/system_applet_proxy.h | ||
| 482 | hle/service/am/service/window_controller.cpp | ||
| 483 | hle/service/am/service/window_controller.h | ||
| 478 | hle/service/am/system_buffer_manager.cpp | 484 | hle/service/am/system_buffer_manager.cpp |
| 479 | hle/service/am/system_buffer_manager.h | 485 | hle/service/am/system_buffer_manager.h |
| 480 | hle/service/am/spsm.cpp | ||
| 481 | hle/service/am/spsm.h | ||
| 482 | hle/service/am/storage_accessor.cpp | ||
| 483 | hle/service/am/storage_accessor.h | ||
| 484 | hle/service/am/storage.cpp | ||
| 485 | hle/service/am/storage.h | ||
| 486 | hle/service/am/window_controller.cpp | ||
| 487 | hle/service/am/window_controller.h | ||
| 488 | hle/service/aoc/aoc_u.cpp | 486 | hle/service/aoc/aoc_u.cpp |
| 489 | hle/service/aoc/aoc_u.h | 487 | hle/service/aoc/aoc_u.h |
| 490 | hle/service/apm/apm.cpp | 488 | hle/service/apm/apm.cpp |
| @@ -668,6 +666,18 @@ add_library(core STATIC | |||
| 668 | hle/service/ldn/ldn.h | 666 | hle/service/ldn/ldn.h |
| 669 | hle/service/ldn/ldn_results.h | 667 | hle/service/ldn/ldn_results.h |
| 670 | hle/service/ldn/ldn_types.h | 668 | hle/service/ldn/ldn_types.h |
| 669 | hle/service/ldn/monitor_service.cpp | ||
| 670 | hle/service/ldn/monitor_service.h | ||
| 671 | hle/service/ldn/sf_monitor_service.cpp | ||
| 672 | hle/service/ldn/sf_monitor_service.h | ||
| 673 | hle/service/ldn/sf_service.cpp | ||
| 674 | hle/service/ldn/sf_service.h | ||
| 675 | hle/service/ldn/sf_service_monitor.cpp | ||
| 676 | hle/service/ldn/sf_service_monitor.h | ||
| 677 | hle/service/ldn/system_local_communication_service.cpp | ||
| 678 | hle/service/ldn/system_local_communication_service.h | ||
| 679 | hle/service/ldn/user_local_communication_service.cpp | ||
| 680 | hle/service/ldn/user_local_communication_service.h | ||
| 671 | hle/service/ldr/ldr.cpp | 681 | hle/service/ldr/ldr.cpp |
| 672 | hle/service/ldr/ldr.h | 682 | hle/service/ldr/ldr.h |
| 673 | hle/service/lm/lm.cpp | 683 | hle/service/lm/lm.cpp |
| @@ -811,6 +821,14 @@ add_library(core STATIC | |||
| 811 | hle/service/nvnflinger/window.h | 821 | hle/service/nvnflinger/window.h |
| 812 | hle/service/olsc/olsc.cpp | 822 | hle/service/olsc/olsc.cpp |
| 813 | hle/service/olsc/olsc.h | 823 | hle/service/olsc/olsc.h |
| 824 | hle/service/omm/omm.cpp | ||
| 825 | hle/service/omm/omm.h | ||
| 826 | hle/service/omm/operation_mode_manager.cpp | ||
| 827 | hle/service/omm/operation_mode_manager.h | ||
| 828 | hle/service/omm/policy_manager_system.cpp | ||
| 829 | hle/service/omm/policy_manager_system.h | ||
| 830 | hle/service/omm/power_state_interface.cpp | ||
| 831 | hle/service/omm/power_state_interface.h | ||
| 814 | hle/service/os/event.cpp | 832 | hle/service/os/event.cpp |
| 815 | hle/service/os/event.h | 833 | hle/service/os/event.h |
| 816 | hle/service/os/multi_wait_holder.cpp | 834 | hle/service/os/multi_wait_holder.cpp |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 8f90eba34..9dc710ba9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -2,11 +2,8 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/am.h" | 4 | #include "core/hle/service/am/am.h" |
| 5 | #include "core/hle/service/am/applet_ae.h" | 5 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" |
| 6 | #include "core/hle/service/am/applet_oe.h" | 6 | #include "core/hle/service/am/service/application_proxy_service.h" |
| 7 | #include "core/hle/service/am/idle.h" | ||
| 8 | #include "core/hle/service/am/omm.h" | ||
| 9 | #include "core/hle/service/am/spsm.h" | ||
| 10 | #include "core/hle/service/server_manager.h" | 7 | #include "core/hle/service/server_manager.h" |
| 11 | 8 | ||
| 12 | namespace Service::AM { | 9 | namespace Service::AM { |
| @@ -14,13 +11,10 @@ namespace Service::AM { | |||
| 14 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 11 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { |
| 15 | auto server_manager = std::make_unique<ServerManager>(system); | 12 | auto server_manager = std::make_unique<ServerManager>(system); |
| 16 | 13 | ||
| 17 | server_manager->RegisterNamedService("appletAE", | 14 | server_manager->RegisterNamedService( |
| 18 | std::make_shared<AppletAE>(nvnflinger, system)); | 15 | "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger)); |
| 19 | server_manager->RegisterNamedService("appletOE", | 16 | server_manager->RegisterNamedService( |
| 20 | std::make_shared<AppletOE>(nvnflinger, system)); | 17 | "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger)); |
| 21 | server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system)); | ||
| 22 | server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system)); | ||
| 23 | server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system)); | ||
| 24 | ServerManager::RunServer(std::move(server_manager)); | 18 | ServerManager::RunServer(std::move(server_manager)); |
| 25 | } | 19 | } |
| 26 | 20 | ||
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index 8c33feb15..46afb3996 100644 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h | |||
| @@ -18,7 +18,7 @@ enum class AppletType { | |||
| 18 | SystemApplet, | 18 | SystemApplet, |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | enum class GameplayRecordingState : u32 { | 21 | enum class GamePlayRecordingState : u32 { |
| 22 | Disabled, | 22 | Disabled, |
| 23 | Enabled, | 23 | Enabled, |
| 24 | }; | 24 | }; |
| @@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 { | |||
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | struct FocusHandlingMode { | 69 | struct FocusHandlingMode { |
| 70 | bool unknown0; | 70 | bool notify; |
| 71 | bool unknown1; | 71 | bool background; |
| 72 | bool unknown2; | 72 | bool suspend; |
| 73 | bool unknown3; | ||
| 74 | }; | 73 | }; |
| 75 | 74 | ||
| 76 | enum class IdleTimeDetectionExtension : u32 { | 75 | enum class IdleTimeDetectionExtension : u32 { |
| @@ -128,6 +127,40 @@ enum class AppletProgramId : u64 { | |||
| 128 | MaxProgramId = 0x0100000000001FFFull, | 127 | MaxProgramId = 0x0100000000001FFFull, |
| 129 | }; | 128 | }; |
| 130 | 129 | ||
| 130 | // This is nn::am::AppletMessage | ||
| 131 | enum class AppletMessage : u32 { | ||
| 132 | None = 0, | ||
| 133 | ChangeIntoForeground = 1, | ||
| 134 | ChangeIntoBackground = 2, | ||
| 135 | Exit = 4, | ||
| 136 | ApplicationExited = 6, | ||
| 137 | FocusStateChanged = 15, | ||
| 138 | Resume = 16, | ||
| 139 | DetectShortPressingHomeButton = 20, | ||
| 140 | DetectLongPressingHomeButton = 21, | ||
| 141 | DetectShortPressingPowerButton = 22, | ||
| 142 | DetectMiddlePressingPowerButton = 23, | ||
| 143 | DetectLongPressingPowerButton = 24, | ||
| 144 | RequestToPrepareSleep = 25, | ||
| 145 | FinishedSleepSequence = 26, | ||
| 146 | SleepRequiredByHighTemperature = 27, | ||
| 147 | SleepRequiredByLowBattery = 28, | ||
| 148 | AutoPowerDown = 29, | ||
| 149 | OperationModeChanged = 30, | ||
| 150 | PerformanceModeChanged = 31, | ||
| 151 | DetectReceivingCecSystemStandby = 32, | ||
| 152 | SdCardRemoved = 33, | ||
| 153 | LaunchApplicationRequested = 50, | ||
| 154 | RequestToDisplay = 51, | ||
| 155 | ShowApplicationLogo = 55, | ||
| 156 | HideApplicationLogo = 56, | ||
| 157 | ForceHideApplicationLogo = 57, | ||
| 158 | FloatingApplicationDetected = 60, | ||
| 159 | DetectShortPressingCaptureButton = 90, | ||
| 160 | AlbumScreenShotTaken = 92, | ||
| 161 | AlbumRecordingSaved = 93, | ||
| 162 | }; | ||
| 163 | |||
| 131 | enum class LibraryAppletMode : u32 { | 164 | enum class LibraryAppletMode : u32 { |
| 132 | AllForeground = 0, | 165 | AllForeground = 0, |
| 133 | PartialForeground = 1, | 166 | PartialForeground = 1, |
| @@ -136,6 +169,11 @@ enum class LibraryAppletMode : u32 { | |||
| 136 | AllForegroundInitiallyHidden = 4, | 169 | AllForegroundInitiallyHidden = 4, |
| 137 | }; | 170 | }; |
| 138 | 171 | ||
| 172 | enum class LaunchParameterKind : u32 { | ||
| 173 | UserChannel = 1, | ||
| 174 | AccountPreselectedUser = 2, | ||
| 175 | }; | ||
| 176 | |||
| 139 | enum class CommonArgumentVersion : u32 { | 177 | enum class CommonArgumentVersion : u32 { |
| 140 | Version0, | 178 | Version0, |
| 141 | Version1, | 179 | Version1, |
| @@ -152,6 +190,22 @@ enum class ThemeColor : u32 { | |||
| 152 | BasicBlack = 3, | 190 | BasicBlack = 3, |
| 153 | }; | 191 | }; |
| 154 | 192 | ||
| 193 | enum class InputDetectionPolicy : u32 { | ||
| 194 | Unknown0 = 0, | ||
| 195 | Unknown1 = 1, | ||
| 196 | }; | ||
| 197 | |||
| 198 | enum class WindowOriginMode : u32 { | ||
| 199 | LowerLeft = 0, | ||
| 200 | UpperLeft = 1, | ||
| 201 | }; | ||
| 202 | |||
| 203 | enum class ProgramSpecifyKind : u32 { | ||
| 204 | ExecuteProgram = 0, | ||
| 205 | JumpToSubApplicationProgramForDevelopment = 1, | ||
| 206 | RestartProgram = 2, | ||
| 207 | }; | ||
| 208 | |||
| 155 | struct CommonArguments { | 209 | struct CommonArguments { |
| 156 | CommonArgumentVersion arguments_version; | 210 | CommonArgumentVersion arguments_version; |
| 157 | CommonArgumentSize size; | 211 | CommonArgumentSize size; |
| @@ -169,6 +223,27 @@ struct AppletIdentityInfo { | |||
| 169 | }; | 223 | }; |
| 170 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | 224 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); |
| 171 | 225 | ||
| 226 | struct AppletAttribute { | ||
| 227 | u8 flag; | ||
| 228 | INSERT_PADDING_BYTES_NOINIT(0x7F); | ||
| 229 | }; | ||
| 230 | static_assert(sizeof(AppletAttribute) == 0x80, "AppletAttribute has incorrect size."); | ||
| 231 | |||
| 232 | // This is nn::oe::DisplayVersion | ||
| 233 | struct DisplayVersion { | ||
| 234 | std::array<char, 0x10> string; | ||
| 235 | }; | ||
| 236 | static_assert(sizeof(DisplayVersion) == 0x10, "DisplayVersion has incorrect size."); | ||
| 237 | |||
| 238 | // This is nn::pdm::ApplicationPlayStatistics | ||
| 239 | struct ApplicationPlayStatistics { | ||
| 240 | u64 application_id; | ||
| 241 | u64 play_time_ns; | ||
| 242 | u64 launch_count; | ||
| 243 | }; | ||
| 244 | static_assert(sizeof(ApplicationPlayStatistics) == 0x18, | ||
| 245 | "ApplicationPlayStatistics has incorrect size."); | ||
| 246 | |||
| 172 | using AppletResourceUserId = u64; | 247 | using AppletResourceUserId = u64; |
| 173 | using ProgramId = u64; | 248 | using ProgramId = u64; |
| 174 | 249 | ||
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index b29ecdfed..4f34d4811 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <list> | ||
| 7 | #include <mutex> | 6 | #include <mutex> |
| 8 | 7 | ||
| 9 | #include "common/math_util.h" | 8 | #include "common/math_util.h" |
| @@ -18,7 +17,6 @@ | |||
| 18 | #include "core/hle/service/am/hid_registration.h" | 17 | #include "core/hle/service/am/hid_registration.h" |
| 19 | #include "core/hle/service/am/managed_layer_holder.h" | 18 | #include "core/hle/service/am/managed_layer_holder.h" |
| 20 | #include "core/hle/service/am/process.h" | 19 | #include "core/hle/service/am/process.h" |
| 21 | #include "core/hle/service/am/storage.h" | ||
| 22 | #include "core/hle/service/am/system_buffer_manager.h" | 20 | #include "core/hle/service/am/system_buffer_manager.h" |
| 23 | 21 | ||
| 24 | namespace Service::AM { | 22 | namespace Service::AM { |
| @@ -76,8 +74,8 @@ struct Applet { | |||
| 76 | u32 application_core_usage_mode{}; | 74 | u32 application_core_usage_mode{}; |
| 77 | 75 | ||
| 78 | // Application functions | 76 | // Application functions |
| 79 | bool gameplay_recording_supported{}; | 77 | bool game_play_recording_supported{}; |
| 80 | GameplayRecordingState gameplay_recording_state{GameplayRecordingState::Disabled}; | 78 | GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; |
| 81 | bool jit_service_launched{}; | 79 | bool jit_service_launched{}; |
| 82 | bool is_running{}; | 80 | bool is_running{}; |
| 83 | bool application_crash_report_enabled{}; | 81 | bool application_crash_report_enabled{}; |
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp deleted file mode 100644 index 1b715dea6..000000000 --- a/src/core/hle/service/am/applet_ae.cpp +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet_ae.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/library_applet_proxy.h" | ||
| 7 | #include "core/hle/service/am/system_applet_proxy.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_) | ||
| 13 | : ServiceFramework{system_, "appletAE"}, nvnflinger{nvnflinger_} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, | ||
| 17 | {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"}, | ||
| 18 | {201, &AppletAE::OpenLibraryAppletProxy, "OpenLibraryAppletProxy"}, | ||
| 19 | {300, nullptr, "OpenOverlayAppletProxy"}, | ||
| 20 | {350, nullptr, "OpenSystemApplicationProxy"}, | ||
| 21 | {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, | ||
| 22 | {410, nullptr, "GetSystemAppletControllerForDebug"}, | ||
| 23 | {1000, nullptr, "GetDebugFunctions"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | |||
| 30 | AppletAE::~AppletAE() = default; | ||
| 31 | |||
| 32 | void AppletAE::OpenSystemAppletProxy(HLERequestContext& ctx) { | ||
| 33 | LOG_DEBUG(Service_AM, "called"); | ||
| 34 | |||
| 35 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 36 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 37 | rb.Push(ResultSuccess); | ||
| 38 | rb.PushIpcInterface<ISystemAppletProxy>(nvnflinger, applet, system); | ||
| 39 | } else { | ||
| 40 | UNIMPLEMENTED(); | ||
| 41 | |||
| 42 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 43 | rb.Push(ResultUnknown); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void AppletAE::OpenLibraryAppletProxy(HLERequestContext& ctx) { | ||
| 48 | LOG_DEBUG(Service_AM, "called"); | ||
| 49 | |||
| 50 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 51 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, applet, system); | ||
| 54 | } else { | ||
| 55 | UNIMPLEMENTED(); | ||
| 56 | |||
| 57 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 58 | rb.Push(ResultUnknown); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | void AppletAE::OpenLibraryAppletProxyOld(HLERequestContext& ctx) { | ||
| 63 | LOG_DEBUG(Service_AM, "called"); | ||
| 64 | |||
| 65 | return OpenLibraryAppletProxy(ctx); | ||
| 66 | } | ||
| 67 | |||
| 68 | std::shared_ptr<Applet> AppletAE::GetAppletFromContext(HLERequestContext& ctx) { | ||
| 69 | const auto aruid = ctx.GetPID(); | ||
| 70 | return system.GetAppletManager().GetByAppletResourceUserId(aruid); | ||
| 71 | } | ||
| 72 | |||
| 73 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h deleted file mode 100644 index 3d7961fa1..000000000 --- a/src/core/hle/service/am/applet_ae.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | |||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service { | ||
| 11 | namespace FileSystem { | ||
| 12 | class FileSystemController; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Nvnflinger { | ||
| 16 | class Nvnflinger; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace AM { | ||
| 20 | |||
| 21 | struct Applet; | ||
| 22 | |||
| 23 | class AppletAE final : public ServiceFramework<AppletAE> { | ||
| 24 | public: | ||
| 25 | explicit AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_); | ||
| 26 | ~AppletAE() override; | ||
| 27 | |||
| 28 | private: | ||
| 29 | void OpenSystemAppletProxy(HLERequestContext& ctx); | ||
| 30 | void OpenLibraryAppletProxy(HLERequestContext& ctx); | ||
| 31 | void OpenLibraryAppletProxyOld(HLERequestContext& ctx); | ||
| 32 | |||
| 33 | std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx); | ||
| 34 | |||
| 35 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 36 | }; | ||
| 37 | |||
| 38 | } // namespace AM | ||
| 39 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 52200d5b2..4c7266f89 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "core/hle/service/am/frontend/applet_controller.h" | 12 | #include "core/hle/service/am/frontend/applet_controller.h" |
| 13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" | 13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" |
| 14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" | 14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" |
| 15 | #include "core/hle/service/am/service/storage.h" | ||
| 15 | #include "hid_core/hid_types.h" | 16 | #include "hid_core/hid_types.h" |
| 16 | 17 | ||
| 17 | namespace Service::AM { | 18 | namespace Service::AM { |
| @@ -303,8 +304,8 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( | |||
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | // Applet was started by frontend, so it is foreground. | 306 | // Applet was started by frontend, so it is foreground. |
| 306 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | 307 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); |
| 307 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | 308 | applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); |
| 308 | applet->focus_state = FocusState::InFocus; | 309 | applet->focus_state = FocusState::InFocus; |
| 309 | 310 | ||
| 310 | this->InsertApplet(std::move(applet)); | 311 | this->InsertApplet(std::move(applet)); |
diff --git a/src/core/hle/service/am/applet_message_queue.cpp b/src/core/hle/service/am/applet_message_queue.cpp index 5ed996b70..83c3c5a55 100644 --- a/src/core/hle/service/am/applet_message_queue.cpp +++ b/src/core/hle/service/am/applet_message_queue.cpp | |||
| @@ -33,7 +33,7 @@ void AppletMessageQueue::PushMessage(AppletMessage msg) { | |||
| 33 | on_new_message->Signal(); | 33 | on_new_message->Signal(); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | 36 | AppletMessage AppletMessageQueue::PopMessage() { |
| 37 | std::scoped_lock lk{lock}; | 37 | std::scoped_lock lk{lock}; |
| 38 | if (messages.empty()) { | 38 | if (messages.empty()) { |
| 39 | on_new_message->Clear(); | 39 | on_new_message->Clear(); |
diff --git a/src/core/hle/service/am/applet_message_queue.h b/src/core/hle/service/am/applet_message_queue.h index 5cb236d47..429b77d37 100644 --- a/src/core/hle/service/am/applet_message_queue.h +++ b/src/core/hle/service/am/applet_message_queue.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <queue> | 6 | #include <queue> |
| 7 | 7 | ||
| 8 | #include "core/hle/service/am/am_types.h" | ||
| 8 | #include "core/hle/service/kernel_helpers.h" | 9 | #include "core/hle/service/kernel_helpers.h" |
| 9 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 10 | 11 | ||
| @@ -16,40 +17,6 @@ namespace Service::AM { | |||
| 16 | 17 | ||
| 17 | class AppletMessageQueue { | 18 | class AppletMessageQueue { |
| 18 | public: | 19 | public: |
| 19 | // This is nn::am::AppletMessage | ||
| 20 | enum class AppletMessage : u32 { | ||
| 21 | None = 0, | ||
| 22 | ChangeIntoForeground = 1, | ||
| 23 | ChangeIntoBackground = 2, | ||
| 24 | Exit = 4, | ||
| 25 | ApplicationExited = 6, | ||
| 26 | FocusStateChanged = 15, | ||
| 27 | Resume = 16, | ||
| 28 | DetectShortPressingHomeButton = 20, | ||
| 29 | DetectLongPressingHomeButton = 21, | ||
| 30 | DetectShortPressingPowerButton = 22, | ||
| 31 | DetectMiddlePressingPowerButton = 23, | ||
| 32 | DetectLongPressingPowerButton = 24, | ||
| 33 | RequestToPrepareSleep = 25, | ||
| 34 | FinishedSleepSequence = 26, | ||
| 35 | SleepRequiredByHighTemperature = 27, | ||
| 36 | SleepRequiredByLowBattery = 28, | ||
| 37 | AutoPowerDown = 29, | ||
| 38 | OperationModeChanged = 30, | ||
| 39 | PerformanceModeChanged = 31, | ||
| 40 | DetectReceivingCecSystemStandby = 32, | ||
| 41 | SdCardRemoved = 33, | ||
| 42 | LaunchApplicationRequested = 50, | ||
| 43 | RequestToDisplay = 51, | ||
| 44 | ShowApplicationLogo = 55, | ||
| 45 | HideApplicationLogo = 56, | ||
| 46 | ForceHideApplicationLogo = 57, | ||
| 47 | FloatingApplicationDetected = 60, | ||
| 48 | DetectShortPressingCaptureButton = 90, | ||
| 49 | AlbumScreenShotTaken = 92, | ||
| 50 | AlbumRecordingSaved = 93, | ||
| 51 | }; | ||
| 52 | |||
| 53 | explicit AppletMessageQueue(Core::System& system); | 20 | explicit AppletMessageQueue(Core::System& system); |
| 54 | ~AppletMessageQueue(); | 21 | ~AppletMessageQueue(); |
| 55 | 22 | ||
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp deleted file mode 100644 index 56bafd162..000000000 --- a/src/core/hle/service/am/applet_oe.cpp +++ /dev/null | |||
| @@ -1,42 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/am.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/applet_oe.h" | ||
| 7 | #include "core/hle/service/am/application_proxy.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_) | ||
| 13 | : ServiceFramework{system_, "appletOE"}, nvnflinger{nvnflinger_} { | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, | ||
| 16 | }; | ||
| 17 | RegisterHandlers(functions); | ||
| 18 | } | ||
| 19 | |||
| 20 | AppletOE::~AppletOE() = default; | ||
| 21 | |||
| 22 | void AppletOE::OpenApplicationProxy(HLERequestContext& ctx) { | ||
| 23 | LOG_DEBUG(Service_AM, "called"); | ||
| 24 | |||
| 25 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 26 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 27 | rb.Push(ResultSuccess); | ||
| 28 | rb.PushIpcInterface<IApplicationProxy>(nvnflinger, applet, system); | ||
| 29 | } else { | ||
| 30 | UNIMPLEMENTED(); | ||
| 31 | |||
| 32 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 33 | rb.Push(ResultUnknown); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | std::shared_ptr<Applet> AppletOE::GetAppletFromContext(HLERequestContext& ctx) { | ||
| 38 | const auto aruid = ctx.GetPID(); | ||
| 39 | return system.GetAppletManager().GetByAppletResourceUserId(aruid); | ||
| 40 | } | ||
| 41 | |||
| 42 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h deleted file mode 100644 index f2ba1c924..000000000 --- a/src/core/hle/service/am/applet_oe.h +++ /dev/null | |||
| @@ -1,37 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | |||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service { | ||
| 11 | namespace FileSystem { | ||
| 12 | class FileSystemController; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Nvnflinger { | ||
| 16 | class Nvnflinger; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace AM { | ||
| 20 | |||
| 21 | struct Applet; | ||
| 22 | |||
| 23 | class AppletOE final : public ServiceFramework<AppletOE> { | ||
| 24 | public: | ||
| 25 | explicit AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_); | ||
| 26 | ~AppletOE() override; | ||
| 27 | |||
| 28 | private: | ||
| 29 | void OpenApplicationProxy(HLERequestContext& ctx); | ||
| 30 | |||
| 31 | std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx); | ||
| 32 | |||
| 33 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace AM | ||
| 37 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/application_functions.cpp b/src/core/hle/service/am/application_functions.cpp deleted file mode 100644 index 51c5be2d1..000000000 --- a/src/core/hle/service/am/application_functions.cpp +++ /dev/null | |||
| @@ -1,594 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "common/uuid.h" | ||
| 6 | #include "core/file_sys/control_metadata.h" | ||
| 7 | #include "core/file_sys/patch_manager.h" | ||
| 8 | #include "core/file_sys/registered_cache.h" | ||
| 9 | #include "core/file_sys/savedata_factory.h" | ||
| 10 | #include "core/hle/service/acc/profile_manager.h" | ||
| 11 | #include "core/hle/service/am/am_results.h" | ||
| 12 | #include "core/hle/service/am/applet.h" | ||
| 13 | #include "core/hle/service/am/application_functions.h" | ||
| 14 | #include "core/hle/service/am/storage.h" | ||
| 15 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 16 | #include "core/hle/service/filesystem/save_data_controller.h" | ||
| 17 | #include "core/hle/service/ipc_helpers.h" | ||
| 18 | #include "core/hle/service/ns/ns.h" | ||
| 19 | #include "core/hle/service/sm/sm.h" | ||
| 20 | |||
| 21 | namespace Service::AM { | ||
| 22 | |||
| 23 | enum class LaunchParameterKind : u32 { | ||
| 24 | UserChannel = 1, | ||
| 25 | AccountPreselectedUser = 2, | ||
| 26 | }; | ||
| 27 | |||
| 28 | IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 29 | : ServiceFramework{system_, "IApplicationFunctions"}, applet{std::move(applet_)} { | ||
| 30 | // clang-format off | ||
| 31 | static const FunctionInfo functions[] = { | ||
| 32 | {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, | ||
| 33 | {10, nullptr, "CreateApplicationAndPushAndRequestToStart"}, | ||
| 34 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, | ||
| 35 | {12, nullptr, "CreateApplicationAndRequestToStart"}, | ||
| 36 | {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"}, | ||
| 37 | {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"}, | ||
| 38 | {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"}, | ||
| 39 | {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"}, | ||
| 40 | {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"}, | ||
| 41 | {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"}, | ||
| 42 | {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"}, | ||
| 43 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, | ||
| 44 | {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, | ||
| 45 | {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, | ||
| 46 | {27, &IApplicationFunctions::CreateCacheStorage, "CreateCacheStorage"}, | ||
| 47 | {28, &IApplicationFunctions::GetSaveDataSizeMax, "GetSaveDataSizeMax"}, | ||
| 48 | {29, nullptr, "GetCacheStorageMax"}, | ||
| 49 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, | ||
| 50 | {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"}, | ||
| 51 | {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, | ||
| 52 | {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, | ||
| 53 | {34, nullptr, "SelectApplicationLicense"}, | ||
| 54 | {35, nullptr, "GetDeviceSaveDataSizeMax"}, | ||
| 55 | {36, nullptr, "GetLimitedApplicationLicense"}, | ||
| 56 | {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, | ||
| 57 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, | ||
| 58 | {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"}, | ||
| 59 | {60, nullptr, "SetMediaPlaybackStateForApplication"}, | ||
| 60 | {65, &IApplicationFunctions::IsGamePlayRecordingSupported, "IsGamePlayRecordingSupported"}, | ||
| 61 | {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"}, | ||
| 62 | {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"}, | ||
| 63 | {68, nullptr, "RequestFlushGamePlayingMovieForDebug"}, | ||
| 64 | {70, nullptr, "RequestToShutdown"}, | ||
| 65 | {71, nullptr, "RequestToReboot"}, | ||
| 66 | {72, nullptr, "RequestToSleep"}, | ||
| 67 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, | ||
| 68 | {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, | ||
| 69 | {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, | ||
| 70 | {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"}, | ||
| 71 | {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, | ||
| 72 | {110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"}, | ||
| 73 | {111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"}, | ||
| 74 | {120, &IApplicationFunctions::ExecuteProgram, "ExecuteProgram"}, | ||
| 75 | {121, &IApplicationFunctions::ClearUserChannel, "ClearUserChannel"}, | ||
| 76 | {122, &IApplicationFunctions::UnpopToUserChannel, "UnpopToUserChannel"}, | ||
| 77 | {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"}, | ||
| 78 | {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||
| 79 | {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"}, | ||
| 80 | {131, nullptr, "SetDelayTimeToAbortOnGpuError"}, | ||
| 81 | {140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"}, | ||
| 82 | {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"}, | ||
| 83 | {150, &IApplicationFunctions::GetNotificationStorageChannelEvent, "GetNotificationStorageChannelEvent"}, | ||
| 84 | {151, nullptr, "TryPopFromNotificationStorageChannel"}, | ||
| 85 | {160, &IApplicationFunctions::GetHealthWarningDisappearedSystemEvent, "GetHealthWarningDisappearedSystemEvent"}, | ||
| 86 | {170, nullptr, "SetHdcpAuthenticationActivated"}, | ||
| 87 | {180, nullptr, "GetLaunchRequiredVersion"}, | ||
| 88 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
| 89 | {190, nullptr, "SendServerMaintenanceOverlayNotification"}, | ||
| 90 | {200, nullptr, "GetLastApplicationExitReason"}, | ||
| 91 | {500, nullptr, "StartContinuousRecordingFlushForDebug"}, | ||
| 92 | {1000, nullptr, "CreateMovieMaker"}, | ||
| 93 | {1001, &IApplicationFunctions::PrepareForJit, "PrepareForJit"}, | ||
| 94 | }; | ||
| 95 | // clang-format on | ||
| 96 | |||
| 97 | RegisterHandlers(functions); | ||
| 98 | } | ||
| 99 | |||
| 100 | IApplicationFunctions::~IApplicationFunctions() = default; | ||
| 101 | |||
| 102 | void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) { | ||
| 103 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 104 | |||
| 105 | std::scoped_lock lk{applet->lock}; | ||
| 106 | applet->application_crash_report_enabled = true; | ||
| 107 | |||
| 108 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 109 | rb.Push(ResultSuccess); | ||
| 110 | } | ||
| 111 | |||
| 112 | void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx) { | ||
| 113 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 114 | |||
| 115 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 116 | rb.Push(ResultSuccess); | ||
| 117 | } | ||
| 118 | |||
| 119 | void IApplicationFunctions::SetApplicationCopyrightImage(HLERequestContext& ctx) { | ||
| 120 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 121 | |||
| 122 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 123 | rb.Push(ResultSuccess); | ||
| 124 | } | ||
| 125 | |||
| 126 | void IApplicationFunctions::SetApplicationCopyrightVisibility(HLERequestContext& ctx) { | ||
| 127 | IPC::RequestParser rp{ctx}; | ||
| 128 | const auto is_visible = rp.Pop<bool>(); | ||
| 129 | |||
| 130 | LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible); | ||
| 131 | |||
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 133 | rb.Push(ResultSuccess); | ||
| 134 | } | ||
| 135 | |||
| 136 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { | ||
| 137 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 138 | |||
| 139 | std::scoped_lock lk{applet->lock}; | ||
| 140 | applet->home_button_long_pressed_blocked = true; | ||
| 141 | applet->home_button_short_pressed_blocked = true; | ||
| 142 | |||
| 143 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 144 | rb.Push(ResultSuccess); | ||
| 145 | } | ||
| 146 | |||
| 147 | void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { | ||
| 148 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 149 | |||
| 150 | std::scoped_lock lk{applet->lock}; | ||
| 151 | applet->home_button_long_pressed_blocked = false; | ||
| 152 | applet->home_button_short_pressed_blocked = false; | ||
| 153 | |||
| 154 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 155 | rb.Push(ResultSuccess); | ||
| 156 | } | ||
| 157 | |||
| 158 | void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) { | ||
| 159 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 160 | |||
| 161 | std::scoped_lock lk{applet->lock}; | ||
| 162 | applet->home_button_long_pressed_blocked = true; | ||
| 163 | applet->home_button_short_pressed_blocked = true; | ||
| 164 | applet->home_button_double_click_enabled = true; | ||
| 165 | |||
| 166 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 167 | rb.Push(ResultSuccess); | ||
| 168 | } | ||
| 169 | |||
| 170 | void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) { | ||
| 171 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 172 | |||
| 173 | std::scoped_lock lk{applet->lock}; | ||
| 174 | applet->home_button_long_pressed_blocked = false; | ||
| 175 | applet->home_button_short_pressed_blocked = false; | ||
| 176 | applet->home_button_double_click_enabled = false; | ||
| 177 | |||
| 178 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 179 | rb.Push(ResultSuccess); | ||
| 180 | } | ||
| 181 | |||
| 182 | void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | ||
| 183 | IPC::RequestParser rp{ctx}; | ||
| 184 | const auto kind = rp.PopEnum<LaunchParameterKind>(); | ||
| 185 | |||
| 186 | LOG_INFO(Service_AM, "called, kind={:08X}", kind); | ||
| 187 | |||
| 188 | std::scoped_lock lk{applet->lock}; | ||
| 189 | |||
| 190 | auto& channel = kind == LaunchParameterKind::UserChannel | ||
| 191 | ? applet->user_channel_launch_parameter | ||
| 192 | : applet->preselected_user_launch_parameter; | ||
| 193 | |||
| 194 | if (channel.empty()) { | ||
| 195 | LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", kind); | ||
| 196 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 197 | rb.Push(AM::ResultNoDataInChannel); | ||
| 198 | return; | ||
| 199 | } | ||
| 200 | |||
| 201 | auto data = channel.back(); | ||
| 202 | channel.pop_back(); | ||
| 203 | |||
| 204 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 205 | rb.Push(ResultSuccess); | ||
| 206 | rb.PushIpcInterface<IStorage>(system, std::move(data)); | ||
| 207 | } | ||
| 208 | |||
| 209 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | ||
| 210 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 211 | |||
| 212 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 213 | rb.Push(ResultSuccess); | ||
| 214 | } | ||
| 215 | |||
| 216 | void IApplicationFunctions::EnsureSaveData(HLERequestContext& ctx) { | ||
| 217 | IPC::RequestParser rp{ctx}; | ||
| 218 | u128 user_id = rp.PopRaw<u128>(); | ||
| 219 | |||
| 220 | LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]); | ||
| 221 | |||
| 222 | FileSys::SaveDataAttribute attribute{}; | ||
| 223 | attribute.title_id = applet->program_id; | ||
| 224 | attribute.user_id = user_id; | ||
| 225 | attribute.type = FileSys::SaveDataType::SaveData; | ||
| 226 | |||
| 227 | FileSys::VirtualDir save_data{}; | ||
| 228 | const auto res = system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( | ||
| 229 | &save_data, FileSys::SaveDataSpaceId::NandUser, attribute); | ||
| 230 | |||
| 231 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 232 | rb.Push(res); | ||
| 233 | rb.Push<u64>(0); | ||
| 234 | } | ||
| 235 | |||
| 236 | void IApplicationFunctions::SetTerminateResult(HLERequestContext& ctx) { | ||
| 237 | // Takes an input u32 Result, no output. | ||
| 238 | // For example, in some cases official apps use this with error 0x2A2 then | ||
| 239 | // uses svcBreak. | ||
| 240 | |||
| 241 | IPC::RequestParser rp{ctx}; | ||
| 242 | u32 result = rp.Pop<u32>(); | ||
| 243 | LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result); | ||
| 244 | |||
| 245 | std::scoped_lock lk{applet->lock}; | ||
| 246 | applet->terminate_result = Result(result); | ||
| 247 | |||
| 248 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 249 | rb.Push(ResultSuccess); | ||
| 250 | } | ||
| 251 | |||
| 252 | void IApplicationFunctions::GetDisplayVersion(HLERequestContext& ctx) { | ||
| 253 | LOG_DEBUG(Service_AM, "called"); | ||
| 254 | |||
| 255 | std::array<u8, 0x10> version_string{}; | ||
| 256 | |||
| 257 | const auto res = [this] { | ||
| 258 | const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(), | ||
| 259 | system.GetContentProvider()}; | ||
| 260 | auto metadata = pm.GetControlMetadata(); | ||
| 261 | if (metadata.first != nullptr) { | ||
| 262 | return metadata; | ||
| 263 | } | ||
| 264 | |||
| 265 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id), | ||
| 266 | system.GetFileSystemController(), | ||
| 267 | system.GetContentProvider()}; | ||
| 268 | return pm_update.GetControlMetadata(); | ||
| 269 | }(); | ||
| 270 | |||
| 271 | if (res.first != nullptr) { | ||
| 272 | const auto& version = res.first->GetVersionString(); | ||
| 273 | std::copy(version.begin(), version.end(), version_string.begin()); | ||
| 274 | } else { | ||
| 275 | static constexpr char default_version[]{"1.0.0"}; | ||
| 276 | std::memcpy(version_string.data(), default_version, sizeof(default_version)); | ||
| 277 | } | ||
| 278 | |||
| 279 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 280 | rb.Push(ResultSuccess); | ||
| 281 | rb.PushRaw(version_string); | ||
| 282 | } | ||
| 283 | |||
| 284 | void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) { | ||
| 285 | // TODO(bunnei): This should be configurable | ||
| 286 | LOG_DEBUG(Service_AM, "called"); | ||
| 287 | |||
| 288 | // Get supported languages from NACP, if possible | ||
| 289 | // Default to 0 (all languages supported) | ||
| 290 | u32 supported_languages = 0; | ||
| 291 | |||
| 292 | const auto res = [this] { | ||
| 293 | const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(), | ||
| 294 | system.GetContentProvider()}; | ||
| 295 | auto metadata = pm.GetControlMetadata(); | ||
| 296 | if (metadata.first != nullptr) { | ||
| 297 | return metadata; | ||
| 298 | } | ||
| 299 | |||
| 300 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id), | ||
| 301 | system.GetFileSystemController(), | ||
| 302 | system.GetContentProvider()}; | ||
| 303 | return pm_update.GetControlMetadata(); | ||
| 304 | }(); | ||
| 305 | |||
| 306 | if (res.first != nullptr) { | ||
| 307 | supported_languages = res.first->GetSupportedLanguages(); | ||
| 308 | } | ||
| 309 | |||
| 310 | // Call IApplicationManagerInterface implementation. | ||
| 311 | auto& service_manager = system.ServiceManager(); | ||
| 312 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | ||
| 313 | auto app_man = ns_am2->GetApplicationManagerInterface(); | ||
| 314 | |||
| 315 | // Get desired application language | ||
| 316 | u8 desired_language{}; | ||
| 317 | const auto res_lang = | ||
| 318 | app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages); | ||
| 319 | if (res_lang != ResultSuccess) { | ||
| 320 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 321 | rb.Push(res_lang); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | |||
| 325 | // Convert to settings language code. | ||
| 326 | u64 language_code{}; | ||
| 327 | const auto res_code = | ||
| 328 | app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language); | ||
| 329 | if (res_code != ResultSuccess) { | ||
| 330 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 331 | rb.Push(res_code); | ||
| 332 | return; | ||
| 333 | } | ||
| 334 | |||
| 335 | LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code); | ||
| 336 | |||
| 337 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 338 | rb.Push(ResultSuccess); | ||
| 339 | rb.Push(language_code); | ||
| 340 | } | ||
| 341 | |||
| 342 | void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) { | ||
| 343 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 344 | |||
| 345 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 346 | rb.Push(ResultSuccess); | ||
| 347 | rb.Push(applet->gameplay_recording_supported); | ||
| 348 | } | ||
| 349 | |||
| 350 | void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) { | ||
| 351 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 352 | |||
| 353 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 354 | rb.Push(ResultSuccess); | ||
| 355 | } | ||
| 356 | |||
| 357 | void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) { | ||
| 358 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 359 | |||
| 360 | IPC::RequestParser rp{ctx}; | ||
| 361 | |||
| 362 | std::scoped_lock lk{applet->lock}; | ||
| 363 | applet->gameplay_recording_state = rp.PopRaw<GameplayRecordingState>(); | ||
| 364 | |||
| 365 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 366 | rb.Push(ResultSuccess); | ||
| 367 | } | ||
| 368 | |||
| 369 | void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) { | ||
| 370 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 371 | |||
| 372 | std::scoped_lock lk{applet->lock}; | ||
| 373 | applet->is_running = true; | ||
| 374 | |||
| 375 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 376 | rb.Push(ResultSuccess); | ||
| 377 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes | ||
| 378 | } | ||
| 379 | |||
| 380 | void IApplicationFunctions::GetPseudoDeviceId(HLERequestContext& ctx) { | ||
| 381 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 382 | |||
| 383 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 384 | rb.Push(ResultSuccess); | ||
| 385 | |||
| 386 | // Returns a 128-bit UUID | ||
| 387 | rb.Push<u64>(0); | ||
| 388 | rb.Push<u64>(0); | ||
| 389 | } | ||
| 390 | |||
| 391 | void IApplicationFunctions::ExtendSaveData(HLERequestContext& ctx) { | ||
| 392 | struct Parameters { | ||
| 393 | FileSys::SaveDataType type; | ||
| 394 | u128 user_id; | ||
| 395 | u64 new_normal_size; | ||
| 396 | u64 new_journal_size; | ||
| 397 | }; | ||
| 398 | static_assert(sizeof(Parameters) == 40); | ||
| 399 | |||
| 400 | IPC::RequestParser rp{ctx}; | ||
| 401 | const auto [type, user_id, new_normal_size, new_journal_size] = rp.PopRaw<Parameters>(); | ||
| 402 | |||
| 403 | LOG_DEBUG(Service_AM, | ||
| 404 | "called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, " | ||
| 405 | "new_journal={:016X}", | ||
| 406 | static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size); | ||
| 407 | |||
| 408 | system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize( | ||
| 409 | type, applet->program_id, user_id, {new_normal_size, new_journal_size}); | ||
| 410 | |||
| 411 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 412 | rb.Push(ResultSuccess); | ||
| 413 | |||
| 414 | // The following value is used upon failure to help the system recover. | ||
| 415 | // Since we always succeed, this should be 0. | ||
| 416 | rb.Push<u64>(0); | ||
| 417 | } | ||
| 418 | |||
| 419 | void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) { | ||
| 420 | struct Parameters { | ||
| 421 | FileSys::SaveDataType type; | ||
| 422 | u128 user_id; | ||
| 423 | }; | ||
| 424 | static_assert(sizeof(Parameters) == 24); | ||
| 425 | |||
| 426 | IPC::RequestParser rp{ctx}; | ||
| 427 | const auto [type, user_id] = rp.PopRaw<Parameters>(); | ||
| 428 | |||
| 429 | LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", type, user_id[1], | ||
| 430 | user_id[0]); | ||
| 431 | |||
| 432 | const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize( | ||
| 433 | type, applet->program_id, user_id); | ||
| 434 | |||
| 435 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 436 | rb.Push(ResultSuccess); | ||
| 437 | rb.Push(size.normal); | ||
| 438 | rb.Push(size.journal); | ||
| 439 | } | ||
| 440 | |||
| 441 | void IApplicationFunctions::CreateCacheStorage(HLERequestContext& ctx) { | ||
| 442 | struct InputParameters { | ||
| 443 | u16 index; | ||
| 444 | s64 size; | ||
| 445 | s64 journal_size; | ||
| 446 | }; | ||
| 447 | static_assert(sizeof(InputParameters) == 24); | ||
| 448 | |||
| 449 | struct OutputParameters { | ||
| 450 | u32 storage_target; | ||
| 451 | u64 required_size; | ||
| 452 | }; | ||
| 453 | static_assert(sizeof(OutputParameters) == 16); | ||
| 454 | |||
| 455 | IPC::RequestParser rp{ctx}; | ||
| 456 | const auto params = rp.PopRaw<InputParameters>(); | ||
| 457 | |||
| 458 | LOG_WARNING(Service_AM, "(STUBBED) called with index={}, size={:#x}, journal_size={:#x}", | ||
| 459 | params.index, params.size, params.journal_size); | ||
| 460 | |||
| 461 | const OutputParameters resp{ | ||
| 462 | .storage_target = 1, | ||
| 463 | .required_size = 0, | ||
| 464 | }; | ||
| 465 | |||
| 466 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 467 | rb.Push(ResultSuccess); | ||
| 468 | rb.PushRaw(resp); | ||
| 469 | } | ||
| 470 | |||
| 471 | void IApplicationFunctions::GetSaveDataSizeMax(HLERequestContext& ctx) { | ||
| 472 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 473 | |||
| 474 | constexpr u64 size_max_normal = 0xFFFFFFF; | ||
| 475 | constexpr u64 size_max_journal = 0xFFFFFFF; | ||
| 476 | |||
| 477 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 478 | rb.Push(ResultSuccess); | ||
| 479 | rb.Push(size_max_normal); | ||
| 480 | rb.Push(size_max_journal); | ||
| 481 | } | ||
| 482 | |||
| 483 | void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) { | ||
| 484 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 485 | |||
| 486 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 487 | rb.Push(ResultSuccess); | ||
| 488 | rb.Push<u32>(0); | ||
| 489 | } | ||
| 490 | |||
| 491 | void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx) { | ||
| 492 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 493 | |||
| 494 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 495 | rb.Push(ResultSuccess); | ||
| 496 | rb.Push<u32>(0); | ||
| 497 | } | ||
| 498 | |||
| 499 | void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) { | ||
| 500 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 501 | |||
| 502 | IPC::RequestParser rp{ctx}; | ||
| 503 | [[maybe_unused]] const auto unk_1 = rp.Pop<u32>(); | ||
| 504 | [[maybe_unused]] const auto unk_2 = rp.Pop<u32>(); | ||
| 505 | const auto program_index = rp.Pop<u64>(); | ||
| 506 | |||
| 507 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 508 | rb.Push(ResultSuccess); | ||
| 509 | |||
| 510 | // Swap user channel ownership into the system so that it will be preserved | ||
| 511 | system.GetUserChannel().swap(applet->user_channel_launch_parameter); | ||
| 512 | system.ExecuteProgram(program_index); | ||
| 513 | } | ||
| 514 | |||
| 515 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { | ||
| 516 | LOG_DEBUG(Service_AM, "called"); | ||
| 517 | |||
| 518 | applet->user_channel_launch_parameter.clear(); | ||
| 519 | |||
| 520 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 521 | rb.Push(ResultSuccess); | ||
| 522 | } | ||
| 523 | |||
| 524 | void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { | ||
| 525 | LOG_DEBUG(Service_AM, "called"); | ||
| 526 | |||
| 527 | IPC::RequestParser rp{ctx}; | ||
| 528 | const auto storage = rp.PopIpcInterface<IStorage>().lock(); | ||
| 529 | if (storage) { | ||
| 530 | applet->user_channel_launch_parameter.push_back(storage->GetData()); | ||
| 531 | } | ||
| 532 | |||
| 533 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 534 | rb.Push(ResultSuccess); | ||
| 535 | } | ||
| 536 | |||
| 537 | void IApplicationFunctions::GetPreviousProgramIndex(HLERequestContext& ctx) { | ||
| 538 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 539 | |||
| 540 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 541 | rb.Push(ResultSuccess); | ||
| 542 | rb.Push<s32>(applet->previous_program_index); | ||
| 543 | } | ||
| 544 | |||
| 545 | void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) { | ||
| 546 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 547 | |||
| 548 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 549 | rb.Push(ResultSuccess); | ||
| 550 | rb.PushCopyObjects(applet->gpu_error_detected_event.GetHandle()); | ||
| 551 | } | ||
| 552 | |||
| 553 | void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) { | ||
| 554 | LOG_DEBUG(Service_AM, "called"); | ||
| 555 | |||
| 556 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 557 | rb.Push(ResultSuccess); | ||
| 558 | rb.PushCopyObjects(applet->friend_invitation_storage_channel_event.GetHandle()); | ||
| 559 | } | ||
| 560 | |||
| 561 | void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) { | ||
| 562 | LOG_DEBUG(Service_AM, "(STUBBED) called"); | ||
| 563 | |||
| 564 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 565 | rb.Push(AM::ResultNoDataInChannel); | ||
| 566 | } | ||
| 567 | |||
| 568 | void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) { | ||
| 569 | LOG_DEBUG(Service_AM, "called"); | ||
| 570 | |||
| 571 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 572 | rb.Push(ResultSuccess); | ||
| 573 | rb.PushCopyObjects(applet->notification_storage_channel_event.GetHandle()); | ||
| 574 | } | ||
| 575 | |||
| 576 | void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) { | ||
| 577 | LOG_DEBUG(Service_AM, "called"); | ||
| 578 | |||
| 579 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 580 | rb.Push(ResultSuccess); | ||
| 581 | rb.PushCopyObjects(applet->health_warning_disappeared_system_event.GetHandle()); | ||
| 582 | } | ||
| 583 | |||
| 584 | void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) { | ||
| 585 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 586 | |||
| 587 | std::scoped_lock lk{applet->lock}; | ||
| 588 | applet->jit_service_launched = true; | ||
| 589 | |||
| 590 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 591 | rb.Push(ResultSuccess); | ||
| 592 | } | ||
| 593 | |||
| 594 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/application_functions.h b/src/core/hle/service/am/application_functions.h deleted file mode 100644 index 55eb21d39..000000000 --- a/src/core/hle/service/am/application_functions.h +++ /dev/null | |||
| @@ -1,58 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | |||
| 13 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | ||
| 14 | public: | ||
| 15 | explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 16 | ~IApplicationFunctions() override; | ||
| 17 | |||
| 18 | private: | ||
| 19 | void PopLaunchParameter(HLERequestContext& ctx); | ||
| 20 | void CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx); | ||
| 21 | void EnsureSaveData(HLERequestContext& ctx); | ||
| 22 | void SetTerminateResult(HLERequestContext& ctx); | ||
| 23 | void GetDisplayVersion(HLERequestContext& ctx); | ||
| 24 | void GetDesiredLanguage(HLERequestContext& ctx); | ||
| 25 | void IsGamePlayRecordingSupported(HLERequestContext& ctx); | ||
| 26 | void InitializeGamePlayRecording(HLERequestContext& ctx); | ||
| 27 | void SetGamePlayRecordingState(HLERequestContext& ctx); | ||
| 28 | void NotifyRunning(HLERequestContext& ctx); | ||
| 29 | void GetPseudoDeviceId(HLERequestContext& ctx); | ||
| 30 | void ExtendSaveData(HLERequestContext& ctx); | ||
| 31 | void GetSaveDataSize(HLERequestContext& ctx); | ||
| 32 | void CreateCacheStorage(HLERequestContext& ctx); | ||
| 33 | void GetSaveDataSizeMax(HLERequestContext& ctx); | ||
| 34 | void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); | ||
| 35 | void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); | ||
| 36 | void BeginBlockingHomeButton(HLERequestContext& ctx); | ||
| 37 | void EndBlockingHomeButton(HLERequestContext& ctx); | ||
| 38 | void EnableApplicationCrashReport(HLERequestContext& ctx); | ||
| 39 | void InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx); | ||
| 40 | void SetApplicationCopyrightImage(HLERequestContext& ctx); | ||
| 41 | void SetApplicationCopyrightVisibility(HLERequestContext& ctx); | ||
| 42 | void QueryApplicationPlayStatistics(HLERequestContext& ctx); | ||
| 43 | void QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx); | ||
| 44 | void ExecuteProgram(HLERequestContext& ctx); | ||
| 45 | void ClearUserChannel(HLERequestContext& ctx); | ||
| 46 | void UnpopToUserChannel(HLERequestContext& ctx); | ||
| 47 | void GetPreviousProgramIndex(HLERequestContext& ctx); | ||
| 48 | void GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx); | ||
| 49 | void GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx); | ||
| 50 | void TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx); | ||
| 51 | void GetNotificationStorageChannelEvent(HLERequestContext& ctx); | ||
| 52 | void GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx); | ||
| 53 | void PrepareForJit(HLERequestContext& ctx); | ||
| 54 | |||
| 55 | const std::shared_ptr<Applet> applet; | ||
| 56 | }; | ||
| 57 | |||
| 58 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/application_proxy.cpp b/src/core/hle/service/am/application_proxy.cpp deleted file mode 100644 index a6fd6d37f..000000000 --- a/src/core/hle/service/am/application_proxy.cpp +++ /dev/null | |||
| @@ -1,115 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/application_functions.h" | ||
| 6 | #include "core/hle/service/am/application_proxy.h" | ||
| 7 | #include "core/hle/service/am/audio_controller.h" | ||
| 8 | #include "core/hle/service/am/common_state_getter.h" | ||
| 9 | #include "core/hle/service/am/debug_functions.h" | ||
| 10 | #include "core/hle/service/am/display_controller.h" | ||
| 11 | #include "core/hle/service/am/library_applet_creator.h" | ||
| 12 | #include "core/hle/service/am/library_applet_self_accessor.h" | ||
| 13 | #include "core/hle/service/am/process_winding_controller.h" | ||
| 14 | #include "core/hle/service/am/self_controller.h" | ||
| 15 | #include "core/hle/service/am/window_controller.h" | ||
| 16 | #include "core/hle/service/ipc_helpers.h" | ||
| 17 | |||
| 18 | namespace Service::AM { | ||
| 19 | |||
| 20 | IApplicationProxy::IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 21 | std::shared_ptr<Applet> applet_, Core::System& system_) | ||
| 22 | : ServiceFramework{system_, "IApplicationProxy"}, nvnflinger{nvnflinger_}, applet{std::move( | ||
| 23 | applet_)} { | ||
| 24 | // clang-format off | ||
| 25 | static const FunctionInfo functions[] = { | ||
| 26 | {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | ||
| 27 | {1, &IApplicationProxy::GetSelfController, "GetSelfController"}, | ||
| 28 | {2, &IApplicationProxy::GetWindowController, "GetWindowController"}, | ||
| 29 | {3, &IApplicationProxy::GetAudioController, "GetAudioController"}, | ||
| 30 | {4, &IApplicationProxy::GetDisplayController, "GetDisplayController"}, | ||
| 31 | {10, &IApplicationProxy::GetProcessWindingController, "GetProcessWindingController"}, | ||
| 32 | {11, &IApplicationProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, | ||
| 33 | {20, &IApplicationProxy::GetApplicationFunctions, "GetApplicationFunctions"}, | ||
| 34 | {1000, &IApplicationProxy::GetDebugFunctions, "GetDebugFunctions"}, | ||
| 35 | }; | ||
| 36 | // clang-format on | ||
| 37 | |||
| 38 | RegisterHandlers(functions); | ||
| 39 | } | ||
| 40 | |||
| 41 | IApplicationProxy::~IApplicationProxy() = default; | ||
| 42 | |||
| 43 | void IApplicationProxy::GetAudioController(HLERequestContext& ctx) { | ||
| 44 | LOG_DEBUG(Service_AM, "called"); | ||
| 45 | |||
| 46 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 47 | rb.Push(ResultSuccess); | ||
| 48 | rb.PushIpcInterface<IAudioController>(system); | ||
| 49 | } | ||
| 50 | |||
| 51 | void IApplicationProxy::GetDisplayController(HLERequestContext& ctx) { | ||
| 52 | LOG_DEBUG(Service_AM, "called"); | ||
| 53 | |||
| 54 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 55 | rb.Push(ResultSuccess); | ||
| 56 | rb.PushIpcInterface<IDisplayController>(system, applet); | ||
| 57 | } | ||
| 58 | |||
| 59 | void IApplicationProxy::GetProcessWindingController(HLERequestContext& ctx) { | ||
| 60 | LOG_DEBUG(Service_AM, "called"); | ||
| 61 | |||
| 62 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 63 | rb.Push(ResultSuccess); | ||
| 64 | rb.PushIpcInterface<IProcessWindingController>(system, applet); | ||
| 65 | } | ||
| 66 | |||
| 67 | void IApplicationProxy::GetDebugFunctions(HLERequestContext& ctx) { | ||
| 68 | LOG_DEBUG(Service_AM, "called"); | ||
| 69 | |||
| 70 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 71 | rb.Push(ResultSuccess); | ||
| 72 | rb.PushIpcInterface<IDebugFunctions>(system); | ||
| 73 | } | ||
| 74 | |||
| 75 | void IApplicationProxy::GetWindowController(HLERequestContext& ctx) { | ||
| 76 | LOG_DEBUG(Service_AM, "called"); | ||
| 77 | |||
| 78 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 79 | rb.Push(ResultSuccess); | ||
| 80 | rb.PushIpcInterface<IWindowController>(system, applet); | ||
| 81 | } | ||
| 82 | |||
| 83 | void IApplicationProxy::GetSelfController(HLERequestContext& ctx) { | ||
| 84 | LOG_DEBUG(Service_AM, "called"); | ||
| 85 | |||
| 86 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 87 | rb.Push(ResultSuccess); | ||
| 88 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); | ||
| 89 | } | ||
| 90 | |||
| 91 | void IApplicationProxy::GetCommonStateGetter(HLERequestContext& ctx) { | ||
| 92 | LOG_DEBUG(Service_AM, "called"); | ||
| 93 | |||
| 94 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 95 | rb.Push(ResultSuccess); | ||
| 96 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); | ||
| 97 | } | ||
| 98 | |||
| 99 | void IApplicationProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | ||
| 100 | LOG_DEBUG(Service_AM, "called"); | ||
| 101 | |||
| 102 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 103 | rb.Push(ResultSuccess); | ||
| 104 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); | ||
| 105 | } | ||
| 106 | |||
| 107 | void IApplicationProxy::GetApplicationFunctions(HLERequestContext& ctx) { | ||
| 108 | LOG_DEBUG(Service_AM, "called"); | ||
| 109 | |||
| 110 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 111 | rb.Push(ResultSuccess); | ||
| 112 | rb.PushIpcInterface<IApplicationFunctions>(system, applet); | ||
| 113 | } | ||
| 114 | |||
| 115 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/application_proxy.h b/src/core/hle/service/am/application_proxy.h deleted file mode 100644 index eb98b095c..000000000 --- a/src/core/hle/service/am/application_proxy.h +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | struct Applet; | ||
| 11 | |||
| 12 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | ||
| 13 | public: | ||
| 14 | explicit IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 15 | std::shared_ptr<Applet> msg_queue_, Core::System& system_); | ||
| 16 | ~IApplicationProxy(); | ||
| 17 | |||
| 18 | private: | ||
| 19 | void GetAudioController(HLERequestContext& ctx); | ||
| 20 | void GetDisplayController(HLERequestContext& ctx); | ||
| 21 | void GetProcessWindingController(HLERequestContext& ctx); | ||
| 22 | void GetDebugFunctions(HLERequestContext& ctx); | ||
| 23 | void GetWindowController(HLERequestContext& ctx); | ||
| 24 | void GetSelfController(HLERequestContext& ctx); | ||
| 25 | void GetCommonStateGetter(HLERequestContext& ctx); | ||
| 26 | void GetLibraryAppletCreator(HLERequestContext& ctx); | ||
| 27 | void GetApplicationFunctions(HLERequestContext& ctx); | ||
| 28 | |||
| 29 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 30 | std::shared_ptr<Applet> applet; | ||
| 31 | }; | ||
| 32 | |||
| 33 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/audio_controller.cpp b/src/core/hle/service/am/audio_controller.cpp deleted file mode 100644 index ae75db174..000000000 --- a/src/core/hle/service/am/audio_controller.cpp +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/audio_controller.h" | ||
| 5 | #include "core/hle/service/ipc_helpers.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | IAudioController::IAudioController(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IAudioController"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"}, | ||
| 14 | {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"}, | ||
| 15 | {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"}, | ||
| 16 | {3, &IAudioController::ChangeMainAppletMasterVolume, "ChangeMainAppletMasterVolume"}, | ||
| 17 | {4, &IAudioController::SetTransparentAudioRate, "SetTransparentVolumeRate"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | |||
| 24 | IAudioController::~IAudioController() = default; | ||
| 25 | |||
| 26 | void IAudioController::SetExpectedMasterVolume(HLERequestContext& ctx) { | ||
| 27 | IPC::RequestParser rp{ctx}; | ||
| 28 | const float main_applet_volume_tmp = rp.Pop<float>(); | ||
| 29 | const float library_applet_volume_tmp = rp.Pop<float>(); | ||
| 30 | |||
| 31 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}", | ||
| 32 | main_applet_volume_tmp, library_applet_volume_tmp); | ||
| 33 | |||
| 34 | // Ensure the volume values remain within the 0-100% range | ||
| 35 | main_applet_volume = std::clamp(main_applet_volume_tmp, min_allowed_volume, max_allowed_volume); | ||
| 36 | library_applet_volume = | ||
| 37 | std::clamp(library_applet_volume_tmp, min_allowed_volume, max_allowed_volume); | ||
| 38 | |||
| 39 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 40 | rb.Push(ResultSuccess); | ||
| 41 | } | ||
| 42 | |||
| 43 | void IAudioController::GetMainAppletExpectedMasterVolume(HLERequestContext& ctx) { | ||
| 44 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume); | ||
| 45 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 46 | rb.Push(ResultSuccess); | ||
| 47 | rb.Push(main_applet_volume); | ||
| 48 | } | ||
| 49 | |||
| 50 | void IAudioController::GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx) { | ||
| 51 | LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume); | ||
| 52 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 53 | rb.Push(ResultSuccess); | ||
| 54 | rb.Push(library_applet_volume); | ||
| 55 | } | ||
| 56 | |||
| 57 | void IAudioController::ChangeMainAppletMasterVolume(HLERequestContext& ctx) { | ||
| 58 | struct Parameters { | ||
| 59 | float volume; | ||
| 60 | s64 fade_time_ns; | ||
| 61 | }; | ||
| 62 | static_assert(sizeof(Parameters) == 16); | ||
| 63 | |||
| 64 | IPC::RequestParser rp{ctx}; | ||
| 65 | const auto parameters = rp.PopRaw<Parameters>(); | ||
| 66 | |||
| 67 | LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", parameters.volume, | ||
| 68 | parameters.fade_time_ns); | ||
| 69 | |||
| 70 | main_applet_volume = std::clamp(parameters.volume, min_allowed_volume, max_allowed_volume); | ||
| 71 | fade_time_ns = std::chrono::nanoseconds{parameters.fade_time_ns}; | ||
| 72 | |||
| 73 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 74 | rb.Push(ResultSuccess); | ||
| 75 | } | ||
| 76 | |||
| 77 | void IAudioController::SetTransparentAudioRate(HLERequestContext& ctx) { | ||
| 78 | IPC::RequestParser rp{ctx}; | ||
| 79 | const float transparent_volume_rate_tmp = rp.Pop<float>(); | ||
| 80 | |||
| 81 | LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate_tmp); | ||
| 82 | |||
| 83 | // Clamp volume range to 0-100%. | ||
| 84 | transparent_volume_rate = | ||
| 85 | std::clamp(transparent_volume_rate_tmp, min_allowed_volume, max_allowed_volume); | ||
| 86 | |||
| 87 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 88 | rb.Push(ResultSuccess); | ||
| 89 | } | ||
| 90 | |||
| 91 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/audio_controller.h b/src/core/hle/service/am/audio_controller.h deleted file mode 100644 index a47e3bad8..000000000 --- a/src/core/hle/service/am/audio_controller.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | class IAudioController final : public ServiceFramework<IAudioController> { | ||
| 11 | public: | ||
| 12 | explicit IAudioController(Core::System& system_); | ||
| 13 | ~IAudioController() override; | ||
| 14 | |||
| 15 | private: | ||
| 16 | void SetExpectedMasterVolume(HLERequestContext& ctx); | ||
| 17 | void GetMainAppletExpectedMasterVolume(HLERequestContext& ctx); | ||
| 18 | void GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx); | ||
| 19 | void ChangeMainAppletMasterVolume(HLERequestContext& ctx); | ||
| 20 | void SetTransparentAudioRate(HLERequestContext& ctx); | ||
| 21 | |||
| 22 | static constexpr float min_allowed_volume = 0.0f; | ||
| 23 | static constexpr float max_allowed_volume = 1.0f; | ||
| 24 | |||
| 25 | float main_applet_volume{0.25f}; | ||
| 26 | float library_applet_volume{max_allowed_volume}; | ||
| 27 | float transparent_volume_rate{min_allowed_volume}; | ||
| 28 | |||
| 29 | // Volume transition fade time in nanoseconds. | ||
| 30 | // e.g. If the main applet volume was 0% and was changed to 50% | ||
| 31 | // with a fade of 50ns, then over the course of 50ns, | ||
| 32 | // the volume will gradually fade up to 50% | ||
| 33 | std::chrono::nanoseconds fade_time_ns{0}; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/common_state_getter.cpp b/src/core/hle/service/am/common_state_getter.cpp deleted file mode 100644 index 937ac0beb..000000000 --- a/src/core/hle/service/am/common_state_getter.cpp +++ /dev/null | |||
| @@ -1,314 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/hle/service/am/am_results.h" | ||
| 6 | #include "core/hle/service/am/applet.h" | ||
| 7 | #include "core/hle/service/am/common_state_getter.h" | ||
| 8 | #include "core/hle/service/am/lock_accessor.h" | ||
| 9 | #include "core/hle/service/apm/apm_controller.h" | ||
| 10 | #include "core/hle/service/apm/apm_interface.h" | ||
| 11 | #include "core/hle/service/ipc_helpers.h" | ||
| 12 | #include "core/hle/service/pm/pm.h" | ||
| 13 | #include "core/hle/service/sm/sm.h" | ||
| 14 | #include "core/hle/service/vi/vi.h" | ||
| 15 | |||
| 16 | namespace Service::AM { | ||
| 17 | |||
| 18 | ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 19 | : ServiceFramework{system_, "ICommonStateGetter"}, applet{std::move(applet_)} { | ||
| 20 | // clang-format off | ||
| 21 | static const FunctionInfo functions[] = { | ||
| 22 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, | ||
| 23 | {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, | ||
| 24 | {2, nullptr, "GetThisAppletKind"}, | ||
| 25 | {3, nullptr, "AllowToEnterSleep"}, | ||
| 26 | {4, nullptr, "DisallowToEnterSleep"}, | ||
| 27 | {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"}, | ||
| 28 | {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"}, | ||
| 29 | {7, nullptr, "GetCradleStatus"}, | ||
| 30 | {8, &ICommonStateGetter::GetBootMode, "GetBootMode"}, | ||
| 31 | {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, | ||
| 32 | {10, &ICommonStateGetter::RequestToAcquireSleepLock, "RequestToAcquireSleepLock"}, | ||
| 33 | {11, nullptr, "ReleaseSleepLock"}, | ||
| 34 | {12, nullptr, "ReleaseSleepLockTransiently"}, | ||
| 35 | {13, &ICommonStateGetter::GetAcquiredSleepLockEvent, "GetAcquiredSleepLockEvent"}, | ||
| 36 | {14, nullptr, "GetWakeupCount"}, | ||
| 37 | {20, nullptr, "PushToGeneralChannel"}, | ||
| 38 | {30, nullptr, "GetHomeButtonReaderLockAccessor"}, | ||
| 39 | {31, &ICommonStateGetter::GetReaderLockAccessorEx, "GetReaderLockAccessorEx"}, | ||
| 40 | {32, nullptr, "GetWriterLockAccessorEx"}, | ||
| 41 | {40, nullptr, "GetCradleFwVersion"}, | ||
| 42 | {50, &ICommonStateGetter::IsVrModeEnabled, "IsVrModeEnabled"}, | ||
| 43 | {51, &ICommonStateGetter::SetVrModeEnabled, "SetVrModeEnabled"}, | ||
| 44 | {52, &ICommonStateGetter::SetLcdBacklighOffEnabled, "SetLcdBacklighOffEnabled"}, | ||
| 45 | {53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"}, | ||
| 46 | {54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"}, | ||
| 47 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, | ||
| 48 | {59, nullptr, "SetVrPositionForDebug"}, | ||
| 49 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, | ||
| 50 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, | ||
| 51 | {62, nullptr, "GetHdcpAuthenticationState"}, | ||
| 52 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, | ||
| 53 | {64, nullptr, "SetTvPowerStateMatchingMode"}, | ||
| 54 | {65, nullptr, "GetApplicationIdByContentActionName"}, | ||
| 55 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, | ||
| 56 | {67, nullptr, "CancelCpuBoostMode"}, | ||
| 57 | {68, &ICommonStateGetter::GetBuiltInDisplayType, "GetBuiltInDisplayType"}, | ||
| 58 | {80, &ICommonStateGetter::PerformSystemButtonPressingIfInFocus, "PerformSystemButtonPressingIfInFocus"}, | ||
| 59 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | ||
| 60 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | ||
| 61 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, | ||
| 62 | {110, nullptr, "OpenMyGpuErrorHandler"}, | ||
| 63 | {120, &ICommonStateGetter::GetAppletLaunchedHistory, "GetAppletLaunchedHistory"}, | ||
| 64 | {200, nullptr, "GetOperationModeSystemInfo"}, | ||
| 65 | {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"}, | ||
| 66 | {400, nullptr, "ActivateMigrationService"}, | ||
| 67 | {401, nullptr, "DeactivateMigrationService"}, | ||
| 68 | {500, nullptr, "DisableSleepTillShutdown"}, | ||
| 69 | {501, nullptr, "SuppressDisablingSleepTemporarily"}, | ||
| 70 | {502, nullptr, "IsSleepEnabled"}, | ||
| 71 | {503, nullptr, "IsDisablingSleepSuppressed"}, | ||
| 72 | {900, &ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, | ||
| 73 | }; | ||
| 74 | // clang-format on | ||
| 75 | |||
| 76 | RegisterHandlers(functions); | ||
| 77 | } | ||
| 78 | |||
| 79 | ICommonStateGetter::~ICommonStateGetter() = default; | ||
| 80 | |||
| 81 | void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) { | ||
| 82 | LOG_DEBUG(Service_AM, "called"); | ||
| 83 | |||
| 84 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 85 | rb.Push(ResultSuccess); | ||
| 86 | rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode | ||
| 87 | } | ||
| 88 | |||
| 89 | void ICommonStateGetter::GetEventHandle(HLERequestContext& ctx) { | ||
| 90 | LOG_DEBUG(Service_AM, "(STUBBED) called"); | ||
| 91 | |||
| 92 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 93 | rb.Push(ResultSuccess); | ||
| 94 | rb.PushCopyObjects(applet->message_queue.GetMessageReceiveEvent()); | ||
| 95 | } | ||
| 96 | |||
| 97 | void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) { | ||
| 98 | LOG_DEBUG(Service_AM, "called"); | ||
| 99 | |||
| 100 | const auto message = applet->message_queue.PopMessage(); | ||
| 101 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 102 | |||
| 103 | if (message == AppletMessageQueue::AppletMessage::None) { | ||
| 104 | LOG_ERROR(Service_AM, "Message queue is empty"); | ||
| 105 | rb.Push(AM::ResultNoMessages); | ||
| 106 | rb.PushEnum<AppletMessageQueue::AppletMessage>(message); | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | |||
| 110 | rb.Push(ResultSuccess); | ||
| 111 | rb.PushEnum<AppletMessageQueue::AppletMessage>(message); | ||
| 112 | } | ||
| 113 | |||
| 114 | void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) { | ||
| 115 | LOG_DEBUG(Service_AM, "(STUBBED) called"); | ||
| 116 | |||
| 117 | std::scoped_lock lk{applet->lock}; | ||
| 118 | |||
| 119 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 120 | rb.Push(ResultSuccess); | ||
| 121 | rb.Push(static_cast<u8>(applet->focus_state)); | ||
| 122 | } | ||
| 123 | |||
| 124 | void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) { | ||
| 125 | const bool use_docked_mode{Settings::IsDockedMode()}; | ||
| 126 | LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); | ||
| 127 | |||
| 128 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 129 | rb.Push(ResultSuccess); | ||
| 130 | rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); | ||
| 131 | } | ||
| 132 | |||
| 133 | void ICommonStateGetter::GetPerformanceMode(HLERequestContext& ctx) { | ||
| 134 | LOG_DEBUG(Service_AM, "called"); | ||
| 135 | |||
| 136 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 137 | rb.Push(ResultSuccess); | ||
| 138 | rb.PushEnum(system.GetAPMController().GetCurrentPerformanceMode()); | ||
| 139 | } | ||
| 140 | |||
| 141 | void ICommonStateGetter::RequestToAcquireSleepLock(HLERequestContext& ctx) { | ||
| 142 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 143 | |||
| 144 | // Sleep lock is acquired immediately. | ||
| 145 | applet->sleep_lock_event.Signal(); | ||
| 146 | |||
| 147 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 148 | rb.Push(ResultSuccess); | ||
| 149 | } | ||
| 150 | |||
| 151 | void ICommonStateGetter::GetReaderLockAccessorEx(HLERequestContext& ctx) { | ||
| 152 | IPC::RequestParser rp{ctx}; | ||
| 153 | const auto unknown = rp.Pop<u32>(); | ||
| 154 | |||
| 155 | LOG_INFO(Service_AM, "called, unknown={}", unknown); | ||
| 156 | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 158 | |||
| 159 | rb.Push(ResultSuccess); | ||
| 160 | rb.PushIpcInterface<ILockAccessor>(system); | ||
| 161 | } | ||
| 162 | |||
| 163 | void ICommonStateGetter::GetAcquiredSleepLockEvent(HLERequestContext& ctx) { | ||
| 164 | LOG_WARNING(Service_AM, "called"); | ||
| 165 | |||
| 166 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 167 | rb.Push(ResultSuccess); | ||
| 168 | rb.PushCopyObjects(applet->sleep_lock_event.GetHandle()); | ||
| 169 | } | ||
| 170 | |||
| 171 | void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) { | ||
| 172 | LOG_DEBUG(Service_AM, "called"); | ||
| 173 | |||
| 174 | std::scoped_lock lk{applet->lock}; | ||
| 175 | |||
| 176 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 177 | rb.Push(ResultSuccess); | ||
| 178 | rb.Push(applet->vr_mode_enabled); | ||
| 179 | } | ||
| 180 | |||
| 181 | void ICommonStateGetter::SetVrModeEnabled(HLERequestContext& ctx) { | ||
| 182 | IPC::RequestParser rp{ctx}; | ||
| 183 | |||
| 184 | std::scoped_lock lk{applet->lock}; | ||
| 185 | applet->vr_mode_enabled = rp.Pop<bool>(); | ||
| 186 | LOG_WARNING(Service_AM, "VR Mode is {}", applet->vr_mode_enabled ? "on" : "off"); | ||
| 187 | |||
| 188 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 189 | rb.Push(ResultSuccess); | ||
| 190 | } | ||
| 191 | |||
| 192 | void ICommonStateGetter::SetLcdBacklighOffEnabled(HLERequestContext& ctx) { | ||
| 193 | IPC::RequestParser rp{ctx}; | ||
| 194 | const auto is_lcd_backlight_off_enabled = rp.Pop<bool>(); | ||
| 195 | |||
| 196 | LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}", | ||
| 197 | is_lcd_backlight_off_enabled); | ||
| 198 | |||
| 199 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 200 | rb.Push(ResultSuccess); | ||
| 201 | } | ||
| 202 | |||
| 203 | void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) { | ||
| 204 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 205 | |||
| 206 | std::scoped_lock lk{applet->lock}; | ||
| 207 | applet->vr_mode_enabled = true; | ||
| 208 | |||
| 209 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 210 | rb.Push(ResultSuccess); | ||
| 211 | } | ||
| 212 | |||
| 213 | void ICommonStateGetter::EndVrModeEx(HLERequestContext& ctx) { | ||
| 214 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 215 | |||
| 216 | std::scoped_lock lk{applet->lock}; | ||
| 217 | applet->vr_mode_enabled = false; | ||
| 218 | |||
| 219 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 220 | rb.Push(ResultSuccess); | ||
| 221 | } | ||
| 222 | |||
| 223 | void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx) { | ||
| 224 | LOG_DEBUG(Service_AM, "called"); | ||
| 225 | |||
| 226 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 227 | rb.Push(ResultSuccess); | ||
| 228 | rb.PushCopyObjects(applet->message_queue.GetOperationModeChangedEvent()); | ||
| 229 | } | ||
| 230 | |||
| 231 | void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) { | ||
| 232 | LOG_DEBUG(Service_AM, "called"); | ||
| 233 | |||
| 234 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 235 | rb.Push(ResultSuccess); | ||
| 236 | |||
| 237 | if (Settings::IsDockedMode()) { | ||
| 238 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth)); | ||
| 239 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight)); | ||
| 240 | } else { | ||
| 241 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth)); | ||
| 242 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight)); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) { | ||
| 247 | LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS"); | ||
| 248 | |||
| 249 | const auto& sm = system.ServiceManager(); | ||
| 250 | const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys"); | ||
| 251 | ASSERT(apm_sys != nullptr); | ||
| 252 | |||
| 253 | apm_sys->SetCpuBoostMode(ctx); | ||
| 254 | } | ||
| 255 | |||
| 256 | void ICommonStateGetter::GetBuiltInDisplayType(HLERequestContext& ctx) { | ||
| 257 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 258 | |||
| 259 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 260 | rb.Push(ResultSuccess); | ||
| 261 | rb.Push(0); | ||
| 262 | } | ||
| 263 | |||
| 264 | void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx) { | ||
| 265 | IPC::RequestParser rp{ctx}; | ||
| 266 | const auto system_button{rp.PopEnum<SystemButtonType>()}; | ||
| 267 | |||
| 268 | LOG_WARNING(Service_AM, "(STUBBED) called, system_button={}", system_button); | ||
| 269 | |||
| 270 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 271 | rb.Push(ResultSuccess); | ||
| 272 | } | ||
| 273 | |||
| 274 | void ICommonStateGetter::GetAppletLaunchedHistory(HLERequestContext& ctx) { | ||
| 275 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 276 | |||
| 277 | std::shared_ptr<Applet> current_applet = applet; | ||
| 278 | std::vector<AppletId> result; | ||
| 279 | |||
| 280 | const size_t count = ctx.GetWriteBufferNumElements<AppletId>(); | ||
| 281 | size_t i; | ||
| 282 | |||
| 283 | for (i = 0; i < count && current_applet != nullptr; i++) { | ||
| 284 | result.push_back(current_applet->applet_id); | ||
| 285 | current_applet = current_applet->caller_applet.lock(); | ||
| 286 | } | ||
| 287 | |||
| 288 | ctx.WriteBuffer(result); | ||
| 289 | |||
| 290 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 291 | rb.Push(ResultSuccess); | ||
| 292 | rb.Push(static_cast<u32>(i)); | ||
| 293 | } | ||
| 294 | |||
| 295 | void ICommonStateGetter::GetSettingsPlatformRegion(HLERequestContext& ctx) { | ||
| 296 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 297 | |||
| 298 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 299 | rb.Push(ResultSuccess); | ||
| 300 | rb.PushEnum(SysPlatformRegion::Global); | ||
| 301 | } | ||
| 302 | |||
| 303 | void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( | ||
| 304 | HLERequestContext& ctx) { | ||
| 305 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 306 | |||
| 307 | std::scoped_lock lk{applet->lock}; | ||
| 308 | applet->request_exit_to_library_applet_at_execute_next_program_enabled = true; | ||
| 309 | |||
| 310 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 311 | rb.Push(ResultSuccess); | ||
| 312 | } | ||
| 313 | |||
| 314 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/common_state_getter.h b/src/core/hle/service/am/common_state_getter.h deleted file mode 100644 index bf652790c..000000000 --- a/src/core/hle/service/am/common_state_getter.h +++ /dev/null | |||
| @@ -1,77 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | struct Applet; | ||
| 14 | |||
| 15 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { | ||
| 16 | public: | ||
| 17 | explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 18 | ~ICommonStateGetter() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | // This is nn::oe::FocusState | ||
| 22 | enum class FocusState : u8 { | ||
| 23 | InFocus = 1, | ||
| 24 | NotInFocus = 2, | ||
| 25 | Background = 3, | ||
| 26 | }; | ||
| 27 | |||
| 28 | // This is nn::oe::OperationMode | ||
| 29 | enum class OperationMode : u8 { | ||
| 30 | Handheld = 0, | ||
| 31 | Docked = 1, | ||
| 32 | }; | ||
| 33 | |||
| 34 | // This is nn::am::service::SystemButtonType | ||
| 35 | enum class SystemButtonType { | ||
| 36 | None, | ||
| 37 | HomeButtonShortPressing, | ||
| 38 | HomeButtonLongPressing, | ||
| 39 | PowerButtonShortPressing, | ||
| 40 | PowerButtonLongPressing, | ||
| 41 | ShutdownSystem, | ||
| 42 | CaptureButtonShortPressing, | ||
| 43 | CaptureButtonLongPressing, | ||
| 44 | }; | ||
| 45 | |||
| 46 | enum class SysPlatformRegion : s32 { | ||
| 47 | Global = 1, | ||
| 48 | Terra = 2, | ||
| 49 | }; | ||
| 50 | |||
| 51 | void GetEventHandle(HLERequestContext& ctx); | ||
| 52 | void ReceiveMessage(HLERequestContext& ctx); | ||
| 53 | void GetCurrentFocusState(HLERequestContext& ctx); | ||
| 54 | void RequestToAcquireSleepLock(HLERequestContext& ctx); | ||
| 55 | void GetAcquiredSleepLockEvent(HLERequestContext& ctx); | ||
| 56 | void GetReaderLockAccessorEx(HLERequestContext& ctx); | ||
| 57 | void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx); | ||
| 58 | void GetOperationMode(HLERequestContext& ctx); | ||
| 59 | void GetPerformanceMode(HLERequestContext& ctx); | ||
| 60 | void GetBootMode(HLERequestContext& ctx); | ||
| 61 | void IsVrModeEnabled(HLERequestContext& ctx); | ||
| 62 | void SetVrModeEnabled(HLERequestContext& ctx); | ||
| 63 | void SetLcdBacklighOffEnabled(HLERequestContext& ctx); | ||
| 64 | void BeginVrModeEx(HLERequestContext& ctx); | ||
| 65 | void EndVrModeEx(HLERequestContext& ctx); | ||
| 66 | void GetDefaultDisplayResolution(HLERequestContext& ctx); | ||
| 67 | void SetCpuBoostMode(HLERequestContext& ctx); | ||
| 68 | void GetBuiltInDisplayType(HLERequestContext& ctx); | ||
| 69 | void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx); | ||
| 70 | void GetAppletLaunchedHistory(HLERequestContext& ctx); | ||
| 71 | void GetSettingsPlatformRegion(HLERequestContext& ctx); | ||
| 72 | void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); | ||
| 73 | |||
| 74 | const std::shared_ptr<Applet> applet; | ||
| 75 | }; | ||
| 76 | |||
| 77 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/display_controller.cpp b/src/core/hle/service/am/display_controller.cpp deleted file mode 100644 index 4d6858348..000000000 --- a/src/core/hle/service/am/display_controller.cpp +++ /dev/null | |||
| @@ -1,135 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet.h" | ||
| 5 | #include "core/hle/service/am/display_controller.h" | ||
| 6 | #include "core/hle/service/ipc_helpers.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | namespace { | ||
| 11 | struct OutputParameters { | ||
| 12 | bool was_written; | ||
| 13 | s32 fbshare_layer_index; | ||
| 14 | }; | ||
| 15 | |||
| 16 | static_assert(sizeof(OutputParameters) == 8, "OutputParameters has wrong size"); | ||
| 17 | } // namespace | ||
| 18 | |||
| 19 | IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 20 | : ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) { | ||
| 21 | // clang-format off | ||
| 22 | static const FunctionInfo functions[] = { | ||
| 23 | {0, nullptr, "GetLastForegroundCaptureImage"}, | ||
| 24 | {1, nullptr, "UpdateLastForegroundCaptureImage"}, | ||
| 25 | {2, nullptr, "GetLastApplicationCaptureImage"}, | ||
| 26 | {3, nullptr, "GetCallerAppletCaptureImage"}, | ||
| 27 | {4, nullptr, "UpdateCallerAppletCaptureImage"}, | ||
| 28 | {5, nullptr, "GetLastForegroundCaptureImageEx"}, | ||
| 29 | {6, nullptr, "GetLastApplicationCaptureImageEx"}, | ||
| 30 | {7, &IDisplayController::GetCallerAppletCaptureImageEx, "GetCallerAppletCaptureImageEx"}, | ||
| 31 | {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"}, | ||
| 32 | {9, nullptr, "CopyBetweenCaptureBuffers"}, | ||
| 33 | {10, nullptr, "AcquireLastApplicationCaptureBuffer"}, | ||
| 34 | {11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, | ||
| 35 | {12, nullptr, "AcquireLastForegroundCaptureBuffer"}, | ||
| 36 | {13, nullptr, "ReleaseLastForegroundCaptureBuffer"}, | ||
| 37 | {14, nullptr, "AcquireCallerAppletCaptureBuffer"}, | ||
| 38 | {15, nullptr, "ReleaseCallerAppletCaptureBuffer"}, | ||
| 39 | {16, nullptr, "AcquireLastApplicationCaptureBufferEx"}, | ||
| 40 | {17, nullptr, "AcquireLastForegroundCaptureBufferEx"}, | ||
| 41 | {18, nullptr, "AcquireCallerAppletCaptureBufferEx"}, | ||
| 42 | {20, nullptr, "ClearCaptureBuffer"}, | ||
| 43 | {21, nullptr, "ClearAppletTransitionBuffer"}, | ||
| 44 | {22, &IDisplayController::AcquireLastApplicationCaptureSharedBuffer, "AcquireLastApplicationCaptureSharedBuffer"}, | ||
| 45 | {23, &IDisplayController::ReleaseLastApplicationCaptureSharedBuffer, "ReleaseLastApplicationCaptureSharedBuffer"}, | ||
| 46 | {24, &IDisplayController::AcquireLastForegroundCaptureSharedBuffer, "AcquireLastForegroundCaptureSharedBuffer"}, | ||
| 47 | {25, &IDisplayController::ReleaseLastForegroundCaptureSharedBuffer, "ReleaseLastForegroundCaptureSharedBuffer"}, | ||
| 48 | {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"}, | ||
| 49 | {27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"}, | ||
| 50 | {28, nullptr, "TakeScreenShotOfOwnLayerEx"}, | ||
| 51 | }; | ||
| 52 | // clang-format on | ||
| 53 | |||
| 54 | RegisterHandlers(functions); | ||
| 55 | } | ||
| 56 | |||
| 57 | IDisplayController::~IDisplayController() = default; | ||
| 58 | |||
| 59 | void IDisplayController::GetCallerAppletCaptureImageEx(HLERequestContext& ctx) { | ||
| 60 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 61 | |||
| 62 | OutputParameters params{}; | ||
| 63 | const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer( | ||
| 64 | ¶ms.was_written, ¶ms.fbshare_layer_index); | ||
| 65 | |||
| 66 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 67 | rb.Push(res); | ||
| 68 | rb.PushRaw(params); | ||
| 69 | } | ||
| 70 | |||
| 71 | void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) { | ||
| 72 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 73 | |||
| 74 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 75 | rb.Push(ResultSuccess); | ||
| 76 | } | ||
| 77 | |||
| 78 | void IDisplayController::AcquireLastApplicationCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 79 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 80 | |||
| 81 | OutputParameters params{}; | ||
| 82 | const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer( | ||
| 83 | ¶ms.was_written, ¶ms.fbshare_layer_index); | ||
| 84 | |||
| 85 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 86 | rb.Push(res); | ||
| 87 | rb.PushRaw(params); | ||
| 88 | } | ||
| 89 | |||
| 90 | void IDisplayController::ReleaseLastApplicationCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 91 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 92 | |||
| 93 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 94 | rb.Push(ResultSuccess); | ||
| 95 | } | ||
| 96 | |||
| 97 | void IDisplayController::AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 98 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 99 | |||
| 100 | OutputParameters params{}; | ||
| 101 | const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer( | ||
| 102 | ¶ms.was_written, ¶ms.fbshare_layer_index); | ||
| 103 | |||
| 104 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 105 | rb.Push(res); | ||
| 106 | rb.PushRaw(params); | ||
| 107 | } | ||
| 108 | |||
| 109 | void IDisplayController::ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 110 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 111 | |||
| 112 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 113 | rb.Push(ResultSuccess); | ||
| 114 | } | ||
| 115 | |||
| 116 | void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 117 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 118 | |||
| 119 | OutputParameters params{}; | ||
| 120 | const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer( | ||
| 121 | ¶ms.was_written, ¶ms.fbshare_layer_index); | ||
| 122 | |||
| 123 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 124 | rb.Push(res); | ||
| 125 | rb.PushRaw(params); | ||
| 126 | } | ||
| 127 | |||
| 128 | void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) { | ||
| 129 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 130 | |||
| 131 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 132 | rb.Push(ResultSuccess); | ||
| 133 | } | ||
| 134 | |||
| 135 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/display_controller.h b/src/core/hle/service/am/display_controller.h deleted file mode 100644 index 75172580c..000000000 --- a/src/core/hle/service/am/display_controller.h +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | struct Applet; | ||
| 11 | |||
| 12 | class IDisplayController final : public ServiceFramework<IDisplayController> { | ||
| 13 | public: | ||
| 14 | explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 15 | ~IDisplayController() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | void GetCallerAppletCaptureImageEx(HLERequestContext& ctx); | ||
| 19 | void TakeScreenShotOfOwnLayer(HLERequestContext& ctx); | ||
| 20 | void AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 21 | void ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 22 | void AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 23 | void ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 24 | void AcquireLastApplicationCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 25 | void ReleaseLastApplicationCaptureSharedBuffer(HLERequestContext& ctx); | ||
| 26 | |||
| 27 | const std::shared_ptr<Applet> applet; | ||
| 28 | }; | ||
| 29 | |||
| 30 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp index 0862c81b6..4cbc80d63 100644 --- a/src/core/hle/service/am/frontend/applet_cabinet.cpp +++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/kernel/k_readable_event.h" | 9 | #include "core/hle/kernel/k_readable_event.h" |
| 10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 11 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
| 12 | #include "core/hle/service/am/storage.h" | 12 | #include "core/hle/service/am/service/storage.h" |
| 13 | #include "core/hle/service/mii/mii_manager.h" | 13 | #include "core/hle/service/mii/mii_manager.h" |
| 14 | #include "core/hle/service/nfc/common/device.h" | 14 | #include "core/hle/service/nfc/common/device.h" |
| 15 | #include "hid_core/hid_core.h" | 15 | #include "hid_core/hid_core.h" |
diff --git a/src/core/hle/service/am/frontend/applet_controller.cpp b/src/core/hle/service/am/frontend/applet_controller.cpp index bd3e49fc4..66f52686d 100644 --- a/src/core/hle/service/am/frontend/applet_controller.cpp +++ b/src/core/hle/service/am/frontend/applet_controller.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 13 | #include "core/hle/service/am/am.h" | 13 | #include "core/hle/service/am/am.h" |
| 14 | #include "core/hle/service/am/frontend/applet_controller.h" | 14 | #include "core/hle/service/am/frontend/applet_controller.h" |
| 15 | #include "core/hle/service/am/storage.h" | 15 | #include "core/hle/service/am/service/storage.h" |
| 16 | #include "hid_core/frontend/emulated_controller.h" | 16 | #include "hid_core/frontend/emulated_controller.h" |
| 17 | #include "hid_core/hid_core.h" | 17 | #include "hid_core/hid_core.h" |
| 18 | #include "hid_core/hid_types.h" | 18 | #include "hid_core/hid_types.h" |
diff --git a/src/core/hle/service/am/frontend/applet_error.cpp b/src/core/hle/service/am/frontend/applet_error.cpp index b97a5f3ea..34ec7013b 100644 --- a/src/core/hle/service/am/frontend/applet_error.cpp +++ b/src/core/hle/service/am/frontend/applet_error.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "core/frontend/applets/error.h" | 10 | #include "core/frontend/applets/error.h" |
| 11 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
| 12 | #include "core/hle/service/am/frontend/applet_error.h" | 12 | #include "core/hle/service/am/frontend/applet_error.h" |
| 13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
| 14 | #include "core/reporter.h" | 14 | #include "core/reporter.h" |
| 15 | 15 | ||
| 16 | namespace Service::AM::Frontend { | 16 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/frontend/applet_general.cpp b/src/core/hle/service/am/frontend/applet_general.cpp index 3c091a602..d2cabb7b5 100644 --- a/src/core/hle/service/am/frontend/applet_general.cpp +++ b/src/core/hle/service/am/frontend/applet_general.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applet_data_broker.h" | 11 | #include "core/hle/service/am/applet_data_broker.h" |
| 12 | #include "core/hle/service/am/frontend/applet_general.h" | 12 | #include "core/hle/service/am/frontend/applet_general.h" |
| 13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
| 14 | #include "core/reporter.h" | 14 | #include "core/reporter.h" |
| 15 | 15 | ||
| 16 | namespace Service::AM::Frontend { | 16 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/frontend/applet_mii_edit.cpp b/src/core/hle/service/am/frontend/applet_mii_edit.cpp index e3d19fb3d..0180ab761 100644 --- a/src/core/hle/service/am/frontend/applet_mii_edit.cpp +++ b/src/core/hle/service/am/frontend/applet_mii_edit.cpp | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "core/frontend/applets/mii_edit.h" | 7 | #include "core/frontend/applets/mii_edit.h" |
| 8 | #include "core/hle/service/am/am.h" | 8 | #include "core/hle/service/am/am.h" |
| 9 | #include "core/hle/service/am/frontend/applet_mii_edit.h" | 9 | #include "core/hle/service/am/frontend/applet_mii_edit.h" |
| 10 | #include "core/hle/service/am/storage.h" | 10 | #include "core/hle/service/am/service/storage.h" |
| 11 | #include "core/hle/service/mii/mii.h" | 11 | #include "core/hle/service/mii/mii.h" |
| 12 | #include "core/hle/service/mii/mii_manager.h" | 12 | #include "core/hle/service/mii/mii_manager.h" |
| 13 | #include "core/hle/service/sm/sm.h" | 13 | #include "core/hle/service/sm/sm.h" |
diff --git a/src/core/hle/service/am/frontend/applet_profile_select.cpp b/src/core/hle/service/am/frontend/applet_profile_select.cpp index efb4053b8..89b5a1eab 100644 --- a/src/core/hle/service/am/frontend/applet_profile_select.cpp +++ b/src/core/hle/service/am/frontend/applet_profile_select.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "core/hle/service/acc/errors.h" | 10 | #include "core/hle/service/acc/errors.h" |
| 11 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
| 12 | #include "core/hle/service/am/frontend/applet_profile_select.h" | 12 | #include "core/hle/service/am/frontend/applet_profile_select.h" |
| 13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
| 14 | 14 | ||
| 15 | namespace Service::AM::Frontend { | 15 | namespace Service::AM::Frontend { |
| 16 | 16 | ||
diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp index 034c62f32..d1bc03018 100644 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include "core/frontend/applets/software_keyboard.h" | 6 | #include "core/frontend/applets/software_keyboard.h" |
| 7 | #include "core/hle/service/am/am.h" | 7 | #include "core/hle/service/am/am.h" |
| 8 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" | 8 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" |
| 9 | #include "core/hle/service/am/storage.h" | 9 | #include "core/hle/service/am/service/storage.h" |
| 10 | 10 | ||
| 11 | namespace Service::AM::Frontend { | 11 | namespace Service::AM::Frontend { |
| 12 | 12 | ||
diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp index 6ee4caf34..bb60260b4 100644 --- a/src/core/hle/service/am/frontend/applet_web_browser.cpp +++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include "core/hle/result.h" | 20 | #include "core/hle/result.h" |
| 21 | #include "core/hle/service/am/am.h" | 21 | #include "core/hle/service/am/am.h" |
| 22 | #include "core/hle/service/am/frontend/applet_web_browser.h" | 22 | #include "core/hle/service/am/frontend/applet_web_browser.h" |
| 23 | #include "core/hle/service/am/storage.h" | 23 | #include "core/hle/service/am/service/storage.h" |
| 24 | #include "core/hle/service/filesystem/filesystem.h" | 24 | #include "core/hle/service/filesystem/filesystem.h" |
| 25 | #include "core/hle/service/ns/iplatform_service_manager.h" | 25 | #include "core/hle/service/ns/iplatform_service_manager.h" |
| 26 | #include "core/loader/loader.h" | 26 | #include "core/loader/loader.h" |
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index db2b04575..e662c6cd6 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp | |||
| @@ -15,11 +15,8 @@ | |||
| 15 | #include "core/frontend/applets/web_browser.h" | 15 | #include "core/frontend/applets/web_browser.h" |
| 16 | #include "core/hle/kernel/k_event.h" | 16 | #include "core/hle/kernel/k_event.h" |
| 17 | #include "core/hle/service/am/am.h" | 17 | #include "core/hle/service/am/am.h" |
| 18 | #include "core/hle/service/am/applet_ae.h" | ||
| 19 | #include "core/hle/service/am/applet_data_broker.h" | 18 | #include "core/hle/service/am/applet_data_broker.h" |
| 20 | #include "core/hle/service/am/applet_manager.h" | 19 | #include "core/hle/service/am/applet_manager.h" |
| 21 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 22 | #include "core/hle/service/am/applet_oe.h" | ||
| 23 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 20 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
| 24 | #include "core/hle/service/am/frontend/applet_controller.h" | 21 | #include "core/hle/service/am/frontend/applet_controller.h" |
| 25 | #include "core/hle/service/am/frontend/applet_error.h" | 22 | #include "core/hle/service/am/frontend/applet_error.h" |
| @@ -29,7 +26,7 @@ | |||
| 29 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" | 26 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" |
| 30 | #include "core/hle/service/am/frontend/applet_web_browser.h" | 27 | #include "core/hle/service/am/frontend/applet_web_browser.h" |
| 31 | #include "core/hle/service/am/frontend/applets.h" | 28 | #include "core/hle/service/am/frontend/applets.h" |
| 32 | #include "core/hle/service/am/storage.h" | 29 | #include "core/hle/service/am/service/storage.h" |
| 33 | #include "core/hle/service/sm/sm.h" | 30 | #include "core/hle/service/sm/sm.h" |
| 34 | 31 | ||
| 35 | namespace Service::AM::Frontend { | 32 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/global_state_controller.cpp b/src/core/hle/service/am/global_state_controller.cpp deleted file mode 100644 index ed0eb7108..000000000 --- a/src/core/hle/service/am/global_state_controller.cpp +++ /dev/null | |||
| @@ -1,34 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/global_state_controller.h" | ||
| 5 | #include "core/hle/service/ipc_helpers.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | IGlobalStateController::IGlobalStateController(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IGlobalStateController"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "RequestToEnterSleep"}, | ||
| 14 | {1, nullptr, "EnterSleep"}, | ||
| 15 | {2, nullptr, "StartSleepSequence"}, | ||
| 16 | {3, nullptr, "StartShutdownSequence"}, | ||
| 17 | {4, nullptr, "StartRebootSequence"}, | ||
| 18 | {9, nullptr, "IsAutoPowerDownRequested"}, | ||
| 19 | {10, nullptr, "LoadAndApplyIdlePolicySettings"}, | ||
| 20 | {11, nullptr, "NotifyCecSettingsChanged"}, | ||
| 21 | {12, nullptr, "SetDefaultHomeButtonLongPressTime"}, | ||
| 22 | {13, nullptr, "UpdateDefaultDisplayResolution"}, | ||
| 23 | {14, nullptr, "ShouldSleepOnBoot"}, | ||
| 24 | {15, nullptr, "GetHdcpAuthenticationFailedEvent"}, | ||
| 25 | {30, nullptr, "OpenCradleFirmwareUpdater"}, | ||
| 26 | }; | ||
| 27 | // clang-format on | ||
| 28 | |||
| 29 | RegisterHandlers(functions); | ||
| 30 | } | ||
| 31 | |||
| 32 | IGlobalStateController::~IGlobalStateController() = default; | ||
| 33 | |||
| 34 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/global_state_controller.h b/src/core/hle/service/am/global_state_controller.h deleted file mode 100644 index 7125464a1..000000000 --- a/src/core/hle/service/am/global_state_controller.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | ||
| 11 | public: | ||
| 12 | explicit IGlobalStateController(Core::System& system_); | ||
| 13 | ~IGlobalStateController() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/home_menu_functions.cpp b/src/core/hle/service/am/home_menu_functions.cpp deleted file mode 100644 index 640e9fbb7..000000000 --- a/src/core/hle/service/am/home_menu_functions.cpp +++ /dev/null | |||
| @@ -1,57 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/home_menu_functions.h" | ||
| 5 | #include "core/hle/service/ipc_helpers.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IHomeMenuFunctions"}, service_context{system, | ||
| 11 | "IHomeMenuFunctions"} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, | ||
| 15 | {11, nullptr, "LockForeground"}, | ||
| 16 | {12, nullptr, "UnlockForeground"}, | ||
| 17 | {20, nullptr, "PopFromGeneralChannel"}, | ||
| 18 | {21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"}, | ||
| 19 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, | ||
| 20 | {31, nullptr, "GetWriterLockAccessorEx"}, | ||
| 21 | {40, nullptr, "IsSleepEnabled"}, | ||
| 22 | {41, nullptr, "IsRebootEnabled"}, | ||
| 23 | {50, nullptr, "LaunchSystemApplet"}, | ||
| 24 | {51, nullptr, "LaunchStarter"}, | ||
| 25 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, | ||
| 26 | {110, nullptr, "IsForceTerminateApplicationDisabledForDebug"}, | ||
| 27 | {200, nullptr, "LaunchDevMenu"}, | ||
| 28 | {1000, nullptr, "SetLastApplicationExitReason"}, | ||
| 29 | }; | ||
| 30 | // clang-format on | ||
| 31 | |||
| 32 | RegisterHandlers(functions); | ||
| 33 | |||
| 34 | pop_from_general_channel_event = | ||
| 35 | service_context.CreateEvent("IHomeMenuFunctions:PopFromGeneralChannelEvent"); | ||
| 36 | } | ||
| 37 | |||
| 38 | IHomeMenuFunctions::~IHomeMenuFunctions() { | ||
| 39 | service_context.CloseEvent(pop_from_general_channel_event); | ||
| 40 | } | ||
| 41 | |||
| 42 | void IHomeMenuFunctions::RequestToGetForeground(HLERequestContext& ctx) { | ||
| 43 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 44 | |||
| 45 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 46 | rb.Push(ResultSuccess); | ||
| 47 | } | ||
| 48 | |||
| 49 | void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(HLERequestContext& ctx) { | ||
| 50 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 51 | |||
| 52 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 53 | rb.Push(ResultSuccess); | ||
| 54 | rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent()); | ||
| 55 | } | ||
| 56 | |||
| 57 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/home_menu_functions.h b/src/core/hle/service/am/home_menu_functions.h deleted file mode 100644 index e082d5d73..000000000 --- a/src/core/hle/service/am/home_menu_functions.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | ||
| 12 | public: | ||
| 13 | explicit IHomeMenuFunctions(Core::System& system_); | ||
| 14 | ~IHomeMenuFunctions() override; | ||
| 15 | |||
| 16 | private: | ||
| 17 | void RequestToGetForeground(HLERequestContext& ctx); | ||
| 18 | void GetPopFromGeneralChannelEvent(HLERequestContext& ctx); | ||
| 19 | |||
| 20 | KernelHelpers::ServiceContext service_context; | ||
| 21 | |||
| 22 | Kernel::KEvent* pop_from_general_channel_event; | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h deleted file mode 100644 index 15b31f67e..000000000 --- a/src/core/hle/service/am/idle.h +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::AM { | ||
| 13 | |||
| 14 | class IdleSys final : public ServiceFramework<IdleSys> { | ||
| 15 | public: | ||
| 16 | explicit IdleSys(Core::System& system_); | ||
| 17 | ~IdleSys() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_accessor.cpp b/src/core/hle/service/am/library_applet_accessor.cpp deleted file mode 100644 index 6b20814f8..000000000 --- a/src/core/hle/service/am/library_applet_accessor.cpp +++ /dev/null | |||
| @@ -1,202 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/scope_exit.h" | ||
| 5 | #include "core/hle/service/am/am_results.h" | ||
| 6 | #include "core/hle/service/am/applet_data_broker.h" | ||
| 7 | #include "core/hle/service/am/frontend/applets.h" | ||
| 8 | #include "core/hle/service/am/library_applet_accessor.h" | ||
| 9 | #include "core/hle/service/am/storage.h" | ||
| 10 | #include "core/hle/service/ipc_helpers.h" | ||
| 11 | |||
| 12 | namespace Service::AM { | ||
| 13 | |||
| 14 | ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, | ||
| 15 | std::shared_ptr<AppletDataBroker> broker_, | ||
| 16 | std::shared_ptr<Applet> applet_) | ||
| 17 | : ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)}, | ||
| 18 | applet{std::move(applet_)} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, | ||
| 22 | {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"}, | ||
| 23 | {10, &ILibraryAppletAccessor::Start, "Start"}, | ||
| 24 | {20, &ILibraryAppletAccessor::RequestExit, "RequestExit"}, | ||
| 25 | {25, nullptr, "Terminate"}, | ||
| 26 | {30, &ILibraryAppletAccessor::GetResult, "GetResult"}, | ||
| 27 | {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, | ||
| 28 | {60, &ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero, "PresetLibraryAppletGpuTimeSliceZero"}, | ||
| 29 | {100, &ILibraryAppletAccessor::PushInData, "PushInData"}, | ||
| 30 | {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"}, | ||
| 31 | {102, nullptr, "PushExtraStorage"}, | ||
| 32 | {103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"}, | ||
| 33 | {104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"}, | ||
| 34 | {105, &ILibraryAppletAccessor::GetPopOutDataEvent, "GetPopOutDataEvent"}, | ||
| 35 | {106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"}, | ||
| 36 | {110, nullptr, "NeedsToExitProcess"}, | ||
| 37 | {120, nullptr, "GetLibraryAppletInfo"}, | ||
| 38 | {150, nullptr, "RequestForAppletToGetForeground"}, | ||
| 39 | {160, &ILibraryAppletAccessor::GetIndirectLayerConsumerHandle, "GetIndirectLayerConsumerHandle"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | |||
| 46 | ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; | ||
| 47 | |||
| 48 | void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) { | ||
| 49 | LOG_DEBUG(Service_AM, "called"); | ||
| 50 | |||
| 51 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle()); | ||
| 54 | } | ||
| 55 | |||
| 56 | void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { | ||
| 57 | LOG_DEBUG(Service_AM, "called"); | ||
| 58 | |||
| 59 | std::scoped_lock lk{applet->lock}; | ||
| 60 | |||
| 61 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 62 | rb.Push(ResultSuccess); | ||
| 63 | rb.Push<u32>(broker->IsCompleted()); | ||
| 64 | } | ||
| 65 | |||
| 66 | void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { | ||
| 67 | LOG_DEBUG(Service_AM, "called"); | ||
| 68 | |||
| 69 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 70 | rb.Push(applet->terminate_result); | ||
| 71 | } | ||
| 72 | |||
| 73 | void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) { | ||
| 74 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 75 | |||
| 76 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 77 | rb.Push(ResultSuccess); | ||
| 78 | } | ||
| 79 | |||
| 80 | void ILibraryAppletAccessor::Start(HLERequestContext& ctx) { | ||
| 81 | LOG_DEBUG(Service_AM, "called"); | ||
| 82 | |||
| 83 | applet->process->Run(); | ||
| 84 | FrontendExecute(); | ||
| 85 | |||
| 86 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 87 | rb.Push(ResultSuccess); | ||
| 88 | } | ||
| 89 | |||
| 90 | void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) { | ||
| 91 | LOG_DEBUG(Service_AM, "called"); | ||
| 92 | |||
| 93 | ASSERT(applet != nullptr); | ||
| 94 | applet->message_queue.RequestExit(); | ||
| 95 | FrontendRequestExit(); | ||
| 96 | |||
| 97 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 98 | rb.Push(ResultSuccess); | ||
| 99 | } | ||
| 100 | |||
| 101 | void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { | ||
| 102 | LOG_DEBUG(Service_AM, "called"); | ||
| 103 | |||
| 104 | IPC::RequestParser rp{ctx}; | ||
| 105 | broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock()); | ||
| 106 | |||
| 107 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 108 | rb.Push(ResultSuccess); | ||
| 109 | } | ||
| 110 | |||
| 111 | void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) { | ||
| 112 | LOG_DEBUG(Service_AM, "called"); | ||
| 113 | |||
| 114 | std::shared_ptr<IStorage> data; | ||
| 115 | const auto res = broker->GetOutData().Pop(&data); | ||
| 116 | |||
| 117 | if (res.IsSuccess()) { | ||
| 118 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 119 | rb.Push(res); | ||
| 120 | rb.PushIpcInterface(std::move(data)); | ||
| 121 | } else { | ||
| 122 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 123 | rb.Push(res); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { | ||
| 128 | LOG_DEBUG(Service_AM, "called"); | ||
| 129 | |||
| 130 | IPC::RequestParser rp{ctx}; | ||
| 131 | broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock()); | ||
| 132 | FrontendExecuteInteractive(); | ||
| 133 | |||
| 134 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 135 | rb.Push(ResultSuccess); | ||
| 136 | } | ||
| 137 | |||
| 138 | void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) { | ||
| 139 | LOG_DEBUG(Service_AM, "called"); | ||
| 140 | |||
| 141 | std::shared_ptr<IStorage> data; | ||
| 142 | const auto res = broker->GetInteractiveOutData().Pop(&data); | ||
| 143 | |||
| 144 | if (res.IsSuccess()) { | ||
| 145 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 146 | rb.Push(res); | ||
| 147 | rb.PushIpcInterface(std::move(data)); | ||
| 148 | } else { | ||
| 149 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 150 | rb.Push(res); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { | ||
| 155 | LOG_DEBUG(Service_AM, "called"); | ||
| 156 | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 158 | rb.Push(ResultSuccess); | ||
| 159 | rb.PushCopyObjects(broker->GetOutData().GetEvent()); | ||
| 160 | } | ||
| 161 | |||
| 162 | void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { | ||
| 163 | LOG_DEBUG(Service_AM, "called"); | ||
| 164 | |||
| 165 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 166 | rb.Push(ResultSuccess); | ||
| 167 | rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent()); | ||
| 168 | } | ||
| 169 | |||
| 170 | void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { | ||
| 171 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 172 | |||
| 173 | // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is | ||
| 174 | // actually used anywhere | ||
| 175 | constexpr u64 handle = 0xdeadbeef; | ||
| 176 | |||
| 177 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 178 | rb.Push(ResultSuccess); | ||
| 179 | rb.Push(handle); | ||
| 180 | } | ||
| 181 | |||
| 182 | void ILibraryAppletAccessor::FrontendExecute() { | ||
| 183 | if (applet->frontend) { | ||
| 184 | applet->frontend->Initialize(); | ||
| 185 | applet->frontend->Execute(); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | void ILibraryAppletAccessor::FrontendExecuteInteractive() { | ||
| 190 | if (applet->frontend) { | ||
| 191 | applet->frontend->ExecuteInteractive(); | ||
| 192 | applet->frontend->Execute(); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | void ILibraryAppletAccessor::FrontendRequestExit() { | ||
| 197 | if (applet->frontend) { | ||
| 198 | applet->frontend->RequestExit(); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_accessor.h b/src/core/hle/service/am/library_applet_accessor.h deleted file mode 100644 index 8be29e003..000000000 --- a/src/core/hle/service/am/library_applet_accessor.h +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | class AppletDataBroker; | ||
| 11 | struct Applet; | ||
| 12 | |||
| 13 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | ||
| 14 | public: | ||
| 15 | explicit ILibraryAppletAccessor(Core::System& system_, | ||
| 16 | std::shared_ptr<AppletDataBroker> broker_, | ||
| 17 | std::shared_ptr<Applet> applet_); | ||
| 18 | ~ILibraryAppletAccessor(); | ||
| 19 | |||
| 20 | protected: | ||
| 21 | void GetAppletStateChangedEvent(HLERequestContext& ctx); | ||
| 22 | void IsCompleted(HLERequestContext& ctx); | ||
| 23 | void GetResult(HLERequestContext& ctx); | ||
| 24 | void PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx); | ||
| 25 | void Start(HLERequestContext& ctx); | ||
| 26 | void RequestExit(HLERequestContext& ctx); | ||
| 27 | void PushInData(HLERequestContext& ctx); | ||
| 28 | void PopOutData(HLERequestContext& ctx); | ||
| 29 | void PushInteractiveInData(HLERequestContext& ctx); | ||
| 30 | void PopInteractiveOutData(HLERequestContext& ctx); | ||
| 31 | void GetPopOutDataEvent(HLERequestContext& ctx); | ||
| 32 | void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); | ||
| 33 | void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); | ||
| 34 | |||
| 35 | void FrontendExecute(); | ||
| 36 | void FrontendExecuteInteractive(); | ||
| 37 | void FrontendRequestExit(); | ||
| 38 | |||
| 39 | const std::shared_ptr<AppletDataBroker> broker; | ||
| 40 | const std::shared_ptr<Applet> applet; | ||
| 41 | }; | ||
| 42 | |||
| 43 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_creator.h b/src/core/hle/service/am/library_applet_creator.h deleted file mode 100644 index 551f287bd..000000000 --- a/src/core/hle/service/am/library_applet_creator.h +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | struct Applet; | ||
| 11 | |||
| 12 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | ||
| 13 | public: | ||
| 14 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 15 | ~ILibraryAppletCreator() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | void CreateLibraryApplet(HLERequestContext& ctx); | ||
| 19 | void CreateStorage(HLERequestContext& ctx); | ||
| 20 | void CreateTransferMemoryStorage(HLERequestContext& ctx); | ||
| 21 | void CreateHandleStorage(HLERequestContext& ctx); | ||
| 22 | |||
| 23 | const std::shared_ptr<Applet> applet; | ||
| 24 | }; | ||
| 25 | |||
| 26 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_proxy.cpp b/src/core/hle/service/am/library_applet_proxy.cpp deleted file mode 100644 index d6108fba3..000000000 --- a/src/core/hle/service/am/library_applet_proxy.cpp +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/audio_controller.h" | ||
| 6 | #include "core/hle/service/am/common_state_getter.h" | ||
| 7 | #include "core/hle/service/am/debug_functions.h" | ||
| 8 | #include "core/hle/service/am/display_controller.h" | ||
| 9 | #include "core/hle/service/am/global_state_controller.h" | ||
| 10 | #include "core/hle/service/am/home_menu_functions.h" | ||
| 11 | #include "core/hle/service/am/library_applet_creator.h" | ||
| 12 | #include "core/hle/service/am/library_applet_proxy.h" | ||
| 13 | #include "core/hle/service/am/library_applet_self_accessor.h" | ||
| 14 | #include "core/hle/service/am/process_winding_controller.h" | ||
| 15 | #include "core/hle/service/am/self_controller.h" | ||
| 16 | #include "core/hle/service/am/window_controller.h" | ||
| 17 | #include "core/hle/service/ipc_helpers.h" | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | ILibraryAppletProxy::ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 22 | std::shared_ptr<Applet> applet_, Core::System& system_) | ||
| 23 | : ServiceFramework{system_, "ILibraryAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move( | ||
| 24 | applet_)} { | ||
| 25 | // clang-format off | ||
| 26 | static const FunctionInfo functions[] = { | ||
| 27 | {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | ||
| 28 | {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"}, | ||
| 29 | {2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"}, | ||
| 30 | {3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"}, | ||
| 31 | {4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"}, | ||
| 32 | {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, | ||
| 33 | {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, | ||
| 34 | {20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"}, | ||
| 35 | {21, &ILibraryAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, | ||
| 36 | {22, &ILibraryAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, | ||
| 37 | {23, &ILibraryAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, | ||
| 38 | {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, | ||
| 39 | }; | ||
| 40 | // clang-format on | ||
| 41 | |||
| 42 | RegisterHandlers(functions); | ||
| 43 | } | ||
| 44 | |||
| 45 | ILibraryAppletProxy::~ILibraryAppletProxy() = default; | ||
| 46 | |||
| 47 | void ILibraryAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { | ||
| 48 | LOG_DEBUG(Service_AM, "called"); | ||
| 49 | |||
| 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 51 | rb.Push(ResultSuccess); | ||
| 52 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); | ||
| 53 | } | ||
| 54 | |||
| 55 | void ILibraryAppletProxy::GetSelfController(HLERequestContext& ctx) { | ||
| 56 | LOG_DEBUG(Service_AM, "called"); | ||
| 57 | |||
| 58 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 59 | rb.Push(ResultSuccess); | ||
| 60 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); | ||
| 61 | } | ||
| 62 | |||
| 63 | void ILibraryAppletProxy::GetWindowController(HLERequestContext& ctx) { | ||
| 64 | LOG_DEBUG(Service_AM, "called"); | ||
| 65 | |||
| 66 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 67 | rb.Push(ResultSuccess); | ||
| 68 | rb.PushIpcInterface<IWindowController>(system, applet); | ||
| 69 | } | ||
| 70 | |||
| 71 | void ILibraryAppletProxy::GetAudioController(HLERequestContext& ctx) { | ||
| 72 | LOG_DEBUG(Service_AM, "called"); | ||
| 73 | |||
| 74 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 75 | rb.Push(ResultSuccess); | ||
| 76 | rb.PushIpcInterface<IAudioController>(system); | ||
| 77 | } | ||
| 78 | |||
| 79 | void ILibraryAppletProxy::GetDisplayController(HLERequestContext& ctx) { | ||
| 80 | LOG_DEBUG(Service_AM, "called"); | ||
| 81 | |||
| 82 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 83 | rb.Push(ResultSuccess); | ||
| 84 | rb.PushIpcInterface<IDisplayController>(system, applet); | ||
| 85 | } | ||
| 86 | |||
| 87 | void ILibraryAppletProxy::GetProcessWindingController(HLERequestContext& ctx) { | ||
| 88 | LOG_DEBUG(Service_AM, "called"); | ||
| 89 | |||
| 90 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 91 | rb.Push(ResultSuccess); | ||
| 92 | rb.PushIpcInterface<IProcessWindingController>(system, applet); | ||
| 93 | } | ||
| 94 | |||
| 95 | void ILibraryAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | ||
| 96 | LOG_DEBUG(Service_AM, "called"); | ||
| 97 | |||
| 98 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 99 | rb.Push(ResultSuccess); | ||
| 100 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); | ||
| 101 | } | ||
| 102 | |||
| 103 | void ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { | ||
| 104 | LOG_DEBUG(Service_AM, "called"); | ||
| 105 | |||
| 106 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 107 | rb.Push(ResultSuccess); | ||
| 108 | rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system, applet); | ||
| 109 | } | ||
| 110 | |||
| 111 | void ILibraryAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { | ||
| 112 | LOG_DEBUG(Service_AM, "called"); | ||
| 113 | |||
| 114 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 115 | rb.Push(ResultSuccess); | ||
| 116 | rb.PushIpcInterface<IAppletCommonFunctions>(system, applet); | ||
| 117 | } | ||
| 118 | |||
| 119 | void ILibraryAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { | ||
| 120 | LOG_DEBUG(Service_AM, "called"); | ||
| 121 | |||
| 122 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 123 | rb.Push(ResultSuccess); | ||
| 124 | rb.PushIpcInterface<IHomeMenuFunctions>(system); | ||
| 125 | } | ||
| 126 | |||
| 127 | void ILibraryAppletProxy::GetGlobalStateController(HLERequestContext& ctx) { | ||
| 128 | LOG_DEBUG(Service_AM, "called"); | ||
| 129 | |||
| 130 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 131 | rb.Push(ResultSuccess); | ||
| 132 | rb.PushIpcInterface<IGlobalStateController>(system); | ||
| 133 | } | ||
| 134 | |||
| 135 | void ILibraryAppletProxy::GetDebugFunctions(HLERequestContext& ctx) { | ||
| 136 | LOG_DEBUG(Service_AM, "called"); | ||
| 137 | |||
| 138 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 139 | rb.Push(ResultSuccess); | ||
| 140 | rb.PushIpcInterface<IDebugFunctions>(system); | ||
| 141 | } | ||
| 142 | |||
| 143 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_proxy.h b/src/core/hle/service/am/library_applet_proxy.h deleted file mode 100644 index 8f7a25897..000000000 --- a/src/core/hle/service/am/library_applet_proxy.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | struct Applet; | ||
| 11 | |||
| 12 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | ||
| 13 | public: | ||
| 14 | explicit ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 15 | std::shared_ptr<Applet> applet_, Core::System& system_); | ||
| 16 | ~ILibraryAppletProxy(); | ||
| 17 | |||
| 18 | private: | ||
| 19 | void GetCommonStateGetter(HLERequestContext& ctx); | ||
| 20 | void GetSelfController(HLERequestContext& ctx); | ||
| 21 | void GetWindowController(HLERequestContext& ctx); | ||
| 22 | void GetAudioController(HLERequestContext& ctx); | ||
| 23 | void GetDisplayController(HLERequestContext& ctx); | ||
| 24 | void GetProcessWindingController(HLERequestContext& ctx); | ||
| 25 | void GetLibraryAppletCreator(HLERequestContext& ctx); | ||
| 26 | void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx); | ||
| 27 | void GetAppletCommonFunctions(HLERequestContext& ctx); | ||
| 28 | void GetHomeMenuFunctions(HLERequestContext& ctx); | ||
| 29 | void GetGlobalStateController(HLERequestContext& ctx); | ||
| 30 | void GetDebugFunctions(HLERequestContext& ctx); | ||
| 31 | |||
| 32 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 33 | std::shared_ptr<Applet> applet; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_self_accessor.cpp b/src/core/hle/service/am/library_applet_self_accessor.cpp deleted file mode 100644 index b560f580b..000000000 --- a/src/core/hle/service/am/library_applet_self_accessor.cpp +++ /dev/null | |||
| @@ -1,338 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/scope_exit.h" | ||
| 5 | #include "core/core_timing.h" | ||
| 6 | #include "core/file_sys/control_metadata.h" | ||
| 7 | #include "core/file_sys/patch_manager.h" | ||
| 8 | #include "core/file_sys/registered_cache.h" | ||
| 9 | #include "core/hle/service/acc/profile_manager.h" | ||
| 10 | #include "core/hle/service/am/am_results.h" | ||
| 11 | #include "core/hle/service/am/applet_data_broker.h" | ||
| 12 | #include "core/hle/service/am/applet_manager.h" | ||
| 13 | #include "core/hle/service/am/frontend/applet_cabinet.h" | ||
| 14 | #include "core/hle/service/am/frontend/applet_controller.h" | ||
| 15 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" | ||
| 16 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" | ||
| 17 | #include "core/hle/service/am/frontend/applets.h" | ||
| 18 | #include "core/hle/service/am/library_applet_self_accessor.h" | ||
| 19 | #include "core/hle/service/am/storage.h" | ||
| 20 | #include "core/hle/service/ipc_helpers.h" | ||
| 21 | #include "core/hle/service/ns/ns.h" | ||
| 22 | #include "core/hle/service/sm/sm.h" | ||
| 23 | #include "hid_core/hid_types.h" | ||
| 24 | |||
| 25 | namespace Service::AM { | ||
| 26 | |||
| 27 | namespace { | ||
| 28 | |||
| 29 | AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) { | ||
| 30 | if (const auto caller_applet = applet->caller_applet.lock(); caller_applet) { | ||
| 31 | // TODO: is this actually the application ID? | ||
| 32 | return { | ||
| 33 | .applet_id = caller_applet->applet_id, | ||
| 34 | .application_id = caller_applet->program_id, | ||
| 35 | }; | ||
| 36 | } else { | ||
| 37 | return { | ||
| 38 | .applet_id = AppletId::QLaunch, | ||
| 39 | .application_id = 0x0100000000001000ull, | ||
| 40 | }; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | } // namespace | ||
| 45 | |||
| 46 | ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_, | ||
| 47 | std::shared_ptr<Applet> applet_) | ||
| 48 | : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)}, | ||
| 49 | broker{applet->caller_applet_broker} { | ||
| 50 | // clang-format off | ||
| 51 | static const FunctionInfo functions[] = { | ||
| 52 | {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, | ||
| 53 | {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"}, | ||
| 54 | {2, &ILibraryAppletSelfAccessor::PopInteractiveInData, "PopInteractiveInData"}, | ||
| 55 | {3, &ILibraryAppletSelfAccessor::PushInteractiveOutData, "PushInteractiveOutData"}, | ||
| 56 | {5, &ILibraryAppletSelfAccessor::GetPopInDataEvent, "GetPopInDataEvent"}, | ||
| 57 | {6, &ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent, "GetPopInteractiveInDataEvent"}, | ||
| 58 | {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, | ||
| 59 | {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, | ||
| 60 | {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"}, | ||
| 61 | {13, &ILibraryAppletSelfAccessor::CanUseApplicationCore, "CanUseApplicationCore"}, | ||
| 62 | {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, | ||
| 63 | {15, nullptr, "GetMainAppletApplicationControlProperty"}, | ||
| 64 | {16, nullptr, "GetMainAppletStorageId"}, | ||
| 65 | {17, nullptr, "GetCallerAppletIdentityInfoStack"}, | ||
| 66 | {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"}, | ||
| 67 | {19, &ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout, "GetDesirableKeyboardLayout"}, | ||
| 68 | {20, nullptr, "PopExtraStorage"}, | ||
| 69 | {25, nullptr, "GetPopExtraStorageEvent"}, | ||
| 70 | {30, nullptr, "UnpopInData"}, | ||
| 71 | {31, nullptr, "UnpopExtraStorage"}, | ||
| 72 | {40, nullptr, "GetIndirectLayerProducerHandle"}, | ||
| 73 | {50, nullptr, "ReportVisibleError"}, | ||
| 74 | {51, nullptr, "ReportVisibleErrorWithErrorContext"}, | ||
| 75 | {60, &ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage, "GetMainAppletApplicationDesiredLanguage"}, | ||
| 76 | {70, &ILibraryAppletSelfAccessor::GetCurrentApplicationId, "GetCurrentApplicationId"}, | ||
| 77 | {80, nullptr, "RequestExitToSelf"}, | ||
| 78 | {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"}, | ||
| 79 | {100, nullptr, "CreateGameMovieTrimmer"}, | ||
| 80 | {101, nullptr, "ReserveResourceForMovieOperation"}, | ||
| 81 | {102, nullptr, "UnreserveResourceForMovieOperation"}, | ||
| 82 | {110, &ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers, "GetMainAppletAvailableUsers"}, | ||
| 83 | {120, nullptr, "GetLaunchStorageInfoForDebug"}, | ||
| 84 | {130, nullptr, "GetGpuErrorDetectedSystemEvent"}, | ||
| 85 | {140, nullptr, "SetApplicationMemoryReservation"}, | ||
| 86 | {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"}, | ||
| 87 | {160, &ILibraryAppletSelfAccessor::Cmd160, "Cmd160"}, | ||
| 88 | }; | ||
| 89 | // clang-format on | ||
| 90 | RegisterHandlers(functions); | ||
| 91 | } | ||
| 92 | |||
| 93 | ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; | ||
| 94 | |||
| 95 | void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) { | ||
| 96 | LOG_INFO(Service_AM, "called"); | ||
| 97 | |||
| 98 | std::shared_ptr<IStorage> data; | ||
| 99 | const auto res = broker->GetInData().Pop(&data); | ||
| 100 | |||
| 101 | if (res.IsSuccess()) { | ||
| 102 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 103 | rb.Push(res); | ||
| 104 | rb.PushIpcInterface(std::move(data)); | ||
| 105 | } else { | ||
| 106 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 107 | rb.Push(res); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) { | ||
| 112 | LOG_INFO(Service_AM, "called"); | ||
| 113 | |||
| 114 | IPC::RequestParser rp{ctx}; | ||
| 115 | broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock()); | ||
| 116 | |||
| 117 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 118 | rb.Push(ResultSuccess); | ||
| 119 | } | ||
| 120 | |||
| 121 | void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) { | ||
| 122 | LOG_INFO(Service_AM, "called"); | ||
| 123 | |||
| 124 | std::shared_ptr<IStorage> data; | ||
| 125 | const auto res = broker->GetInteractiveInData().Pop(&data); | ||
| 126 | |||
| 127 | if (res.IsSuccess()) { | ||
| 128 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 129 | rb.Push(res); | ||
| 130 | rb.PushIpcInterface(std::move(data)); | ||
| 131 | } else { | ||
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 133 | rb.Push(res); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx) { | ||
| 138 | LOG_INFO(Service_AM, "called"); | ||
| 139 | |||
| 140 | IPC::RequestParser rp{ctx}; | ||
| 141 | broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock()); | ||
| 142 | |||
| 143 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 144 | rb.Push(ResultSuccess); | ||
| 145 | } | ||
| 146 | |||
| 147 | void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) { | ||
| 148 | LOG_INFO(Service_AM, "called"); | ||
| 149 | |||
| 150 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 151 | rb.Push(ResultSuccess); | ||
| 152 | rb.PushCopyObjects(broker->GetInData().GetEvent()); | ||
| 153 | } | ||
| 154 | |||
| 155 | void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) { | ||
| 156 | LOG_INFO(Service_AM, "called"); | ||
| 157 | |||
| 158 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 159 | rb.Push(ResultSuccess); | ||
| 160 | rb.PushCopyObjects(broker->GetInteractiveInData().GetEvent()); | ||
| 161 | } | ||
| 162 | |||
| 163 | void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { | ||
| 164 | LOG_INFO(Service_AM, "called"); | ||
| 165 | |||
| 166 | system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid); | ||
| 167 | broker->SignalCompletion(); | ||
| 168 | |||
| 169 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 170 | rb.Push(ResultSuccess); | ||
| 171 | } | ||
| 172 | |||
| 173 | void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { | ||
| 174 | struct LibraryAppletInfo { | ||
| 175 | AppletId applet_id; | ||
| 176 | LibraryAppletMode library_applet_mode; | ||
| 177 | }; | ||
| 178 | |||
| 179 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 180 | |||
| 181 | const LibraryAppletInfo applet_info{ | ||
| 182 | .applet_id = applet->applet_id, | ||
| 183 | .library_applet_mode = applet->library_applet_mode, | ||
| 184 | }; | ||
| 185 | |||
| 186 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 187 | rb.Push(ResultSuccess); | ||
| 188 | rb.PushRaw(applet_info); | ||
| 189 | } | ||
| 190 | |||
| 191 | void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) { | ||
| 192 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 193 | |||
| 194 | const AppletIdentityInfo applet_info{ | ||
| 195 | .applet_id = AppletId::QLaunch, | ||
| 196 | .application_id = 0x0100000000001000ull, | ||
| 197 | }; | ||
| 198 | |||
| 199 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 200 | rb.Push(ResultSuccess); | ||
| 201 | rb.PushRaw(applet_info); | ||
| 202 | } | ||
| 203 | |||
| 204 | void ILibraryAppletSelfAccessor::CanUseApplicationCore(HLERequestContext& ctx) { | ||
| 205 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 206 | |||
| 207 | // TODO: This appears to read the NPDM from state and check the core mask of the applet. | ||
| 208 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 209 | rb.Push(ResultSuccess); | ||
| 210 | rb.Push<u8>(0); | ||
| 211 | } | ||
| 212 | |||
| 213 | void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { | ||
| 214 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 215 | |||
| 216 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 217 | rb.Push(ResultSuccess); | ||
| 218 | rb.PushRaw(GetCallerIdentity(applet)); | ||
| 219 | } | ||
| 220 | |||
| 221 | void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) { | ||
| 222 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 223 | |||
| 224 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 225 | rb.Push(ResultSuccess); | ||
| 226 | rb.Push<u32>(0); | ||
| 227 | } | ||
| 228 | |||
| 229 | void ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx) { | ||
| 230 | // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage | ||
| 231 | auto identity = GetCallerIdentity(applet); | ||
| 232 | |||
| 233 | // TODO(bunnei): This should be configurable | ||
| 234 | LOG_DEBUG(Service_AM, "called"); | ||
| 235 | |||
| 236 | // Get supported languages from NACP, if possible | ||
| 237 | // Default to 0 (all languages supported) | ||
| 238 | u32 supported_languages = 0; | ||
| 239 | |||
| 240 | const auto res = [this, identity] { | ||
| 241 | const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(), | ||
| 242 | system.GetContentProvider()}; | ||
| 243 | auto metadata = pm.GetControlMetadata(); | ||
| 244 | if (metadata.first != nullptr) { | ||
| 245 | return metadata; | ||
| 246 | } | ||
| 247 | |||
| 248 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id), | ||
| 249 | system.GetFileSystemController(), | ||
| 250 | system.GetContentProvider()}; | ||
| 251 | return pm_update.GetControlMetadata(); | ||
| 252 | }(); | ||
| 253 | |||
| 254 | if (res.first != nullptr) { | ||
| 255 | supported_languages = res.first->GetSupportedLanguages(); | ||
| 256 | } | ||
| 257 | |||
| 258 | // Call IApplicationManagerInterface implementation. | ||
| 259 | auto& service_manager = system.ServiceManager(); | ||
| 260 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | ||
| 261 | auto app_man = ns_am2->GetApplicationManagerInterface(); | ||
| 262 | |||
| 263 | // Get desired application language | ||
| 264 | u8 desired_language{}; | ||
| 265 | const auto res_lang = | ||
| 266 | app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages); | ||
| 267 | if (res_lang != ResultSuccess) { | ||
| 268 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 269 | rb.Push(res_lang); | ||
| 270 | return; | ||
| 271 | } | ||
| 272 | |||
| 273 | // Convert to settings language code. | ||
| 274 | u64 language_code{}; | ||
| 275 | const auto res_code = | ||
| 276 | app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language); | ||
| 277 | if (res_code != ResultSuccess) { | ||
| 278 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 279 | rb.Push(res_code); | ||
| 280 | return; | ||
| 281 | } | ||
| 282 | |||
| 283 | LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code); | ||
| 284 | |||
| 285 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 286 | rb.Push(ResultSuccess); | ||
| 287 | rb.Push(language_code); | ||
| 288 | } | ||
| 289 | |||
| 290 | void ILibraryAppletSelfAccessor::GetCurrentApplicationId(HLERequestContext& ctx) { | ||
| 291 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 292 | |||
| 293 | u64 application_id = 0; | ||
| 294 | if (auto caller_applet = applet->caller_applet.lock(); caller_applet) { | ||
| 295 | application_id = caller_applet->program_id; | ||
| 296 | } | ||
| 297 | |||
| 298 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 299 | rb.Push(ResultSuccess); | ||
| 300 | rb.Push(application_id); | ||
| 301 | } | ||
| 302 | |||
| 303 | void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) { | ||
| 304 | const Service::Account::ProfileManager manager{}; | ||
| 305 | bool is_empty{true}; | ||
| 306 | s32 user_count{-1}; | ||
| 307 | |||
| 308 | LOG_INFO(Service_AM, "called"); | ||
| 309 | |||
| 310 | if (manager.GetUserCount() > 0) { | ||
| 311 | is_empty = false; | ||
| 312 | user_count = static_cast<s32>(manager.GetUserCount()); | ||
| 313 | ctx.WriteBuffer(manager.GetAllUsers()); | ||
| 314 | } | ||
| 315 | |||
| 316 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 317 | rb.Push(ResultSuccess); | ||
| 318 | rb.Push<u8>(is_empty); | ||
| 319 | rb.Push(user_count); | ||
| 320 | } | ||
| 321 | |||
| 322 | void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext& ctx) { | ||
| 323 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 324 | |||
| 325 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 326 | rb.Push(ResultSuccess); | ||
| 327 | rb.Push<u8>(0); | ||
| 328 | } | ||
| 329 | |||
| 330 | void ILibraryAppletSelfAccessor::Cmd160(HLERequestContext& ctx) { | ||
| 331 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 332 | |||
| 333 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 334 | rb.Push(ResultSuccess); | ||
| 335 | rb.Push<u64>(0); | ||
| 336 | } | ||
| 337 | |||
| 338 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_self_accessor.h b/src/core/hle/service/am/library_applet_self_accessor.h deleted file mode 100644 index 8717a989a..000000000 --- a/src/core/hle/service/am/library_applet_self_accessor.h +++ /dev/null | |||
| @@ -1,44 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <deque> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | class AppletDataBroker; | ||
| 14 | struct Applet; | ||
| 15 | |||
| 16 | class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { | ||
| 17 | public: | ||
| 18 | explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 19 | ~ILibraryAppletSelfAccessor() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | void PopInData(HLERequestContext& ctx); | ||
| 23 | void PushOutData(HLERequestContext& ctx); | ||
| 24 | void PopInteractiveInData(HLERequestContext& ctx); | ||
| 25 | void PushInteractiveOutData(HLERequestContext& ctx); | ||
| 26 | void GetPopInDataEvent(HLERequestContext& ctx); | ||
| 27 | void GetPopInteractiveInDataEvent(HLERequestContext& ctx); | ||
| 28 | void GetLibraryAppletInfo(HLERequestContext& ctx); | ||
| 29 | void GetMainAppletIdentityInfo(HLERequestContext& ctx); | ||
| 30 | void CanUseApplicationCore(HLERequestContext& ctx); | ||
| 31 | void ExitProcessAndReturn(HLERequestContext& ctx); | ||
| 32 | void GetCallerAppletIdentityInfo(HLERequestContext& ctx); | ||
| 33 | void GetDesirableKeyboardLayout(HLERequestContext& ctx); | ||
| 34 | void GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx); | ||
| 35 | void GetCurrentApplicationId(HLERequestContext& ctx); | ||
| 36 | void GetMainAppletAvailableUsers(HLERequestContext& ctx); | ||
| 37 | void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx); | ||
| 38 | void Cmd160(HLERequestContext& ctx); | ||
| 39 | |||
| 40 | const std::shared_ptr<Applet> applet; | ||
| 41 | const std::shared_ptr<AppletDataBroker> broker; | ||
| 42 | }; | ||
| 43 | |||
| 44 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/lock_accessor.cpp b/src/core/hle/service/am/lock_accessor.cpp deleted file mode 100644 index d0bd8d95e..000000000 --- a/src/core/hle/service/am/lock_accessor.cpp +++ /dev/null | |||
| @@ -1,71 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/lock_accessor.h" | ||
| 5 | #include "core/hle/service/ipc_helpers.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | ILockAccessor::ILockAccessor(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ILockAccessor"}, service_context{system_, "ILockAccessor"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {1, &ILockAccessor::TryLock, "TryLock"}, | ||
| 14 | {2, &ILockAccessor::Unlock, "Unlock"}, | ||
| 15 | {3, &ILockAccessor::GetEvent, "GetEvent"}, | ||
| 16 | {4,&ILockAccessor::IsLocked, "IsLocked"}, | ||
| 17 | }; | ||
| 18 | // clang-format on | ||
| 19 | |||
| 20 | RegisterHandlers(functions); | ||
| 21 | |||
| 22 | lock_event = service_context.CreateEvent("ILockAccessor::LockEvent"); | ||
| 23 | } | ||
| 24 | |||
| 25 | ILockAccessor::~ILockAccessor() { | ||
| 26 | service_context.CloseEvent(lock_event); | ||
| 27 | }; | ||
| 28 | |||
| 29 | void ILockAccessor::TryLock(HLERequestContext& ctx) { | ||
| 30 | IPC::RequestParser rp{ctx}; | ||
| 31 | const auto return_handle = rp.Pop<bool>(); | ||
| 32 | |||
| 33 | LOG_WARNING(Service_AM, "(STUBBED) called, return_handle={}", return_handle); | ||
| 34 | |||
| 35 | // TODO: When return_handle is true this function should return the lock handle | ||
| 36 | |||
| 37 | is_locked = true; | ||
| 38 | |||
| 39 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 40 | rb.Push(ResultSuccess); | ||
| 41 | rb.Push<u8>(is_locked); | ||
| 42 | } | ||
| 43 | |||
| 44 | void ILockAccessor::Unlock(HLERequestContext& ctx) { | ||
| 45 | LOG_INFO(Service_AM, "called"); | ||
| 46 | |||
| 47 | is_locked = false; | ||
| 48 | |||
| 49 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 50 | rb.Push(ResultSuccess); | ||
| 51 | } | ||
| 52 | |||
| 53 | void ILockAccessor::GetEvent(HLERequestContext& ctx) { | ||
| 54 | LOG_INFO(Service_AM, "called"); | ||
| 55 | |||
| 56 | lock_event->Signal(); | ||
| 57 | |||
| 58 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 59 | rb.Push(ResultSuccess); | ||
| 60 | rb.PushCopyObjects(lock_event->GetReadableEvent()); | ||
| 61 | } | ||
| 62 | |||
| 63 | void ILockAccessor::IsLocked(HLERequestContext& ctx) { | ||
| 64 | LOG_INFO(Service_AM, "called"); | ||
| 65 | |||
| 66 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 67 | rb.Push(ResultSuccess); | ||
| 68 | rb.Push<u8>(is_locked); | ||
| 69 | } | ||
| 70 | |||
| 71 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/lock_accessor.h b/src/core/hle/service/am/lock_accessor.h deleted file mode 100644 index 626f60e07..000000000 --- a/src/core/hle/service/am/lock_accessor.h +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/kernel_helpers.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class ILockAccessor final : public ServiceFramework<ILockAccessor> { | ||
| 12 | public: | ||
| 13 | explicit ILockAccessor(Core::System& system_); | ||
| 14 | ~ILockAccessor() override; | ||
| 15 | |||
| 16 | private: | ||
| 17 | void TryLock(HLERequestContext& ctx); | ||
| 18 | void Unlock(HLERequestContext& ctx); | ||
| 19 | void GetEvent(HLERequestContext& ctx); | ||
| 20 | void IsLocked(HLERequestContext& ctx); | ||
| 21 | |||
| 22 | bool is_locked{}; | ||
| 23 | |||
| 24 | Kernel::KEvent* lock_event; | ||
| 25 | KernelHelpers::ServiceContext service_context; | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h deleted file mode 100644 index 73d0c82d5..000000000 --- a/src/core/hle/service/am/omm.h +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::AM { | ||
| 13 | |||
| 14 | class OMM final : public ServiceFramework<OMM> { | ||
| 15 | public: | ||
| 16 | explicit OMM(Core::System& system_); | ||
| 17 | ~OMM() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/process_winding_controller.cpp b/src/core/hle/service/am/process_winding_controller.cpp deleted file mode 100644 index b48b52797..000000000 --- a/src/core/hle/service/am/process_winding_controller.cpp +++ /dev/null | |||
| @@ -1,56 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/frontend/applets.h" | ||
| 5 | #include "core/hle/service/am/library_applet_accessor.h" | ||
| 6 | #include "core/hle/service/am/process_winding_controller.h" | ||
| 7 | #include "core/hle/service/ipc_helpers.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IProcessWindingController::IProcessWindingController(Core::System& system_, | ||
| 12 | std::shared_ptr<Applet> applet_) | ||
| 13 | : ServiceFramework{system_, "IProcessWindingController"}, applet{std::move(applet_)} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"}, | ||
| 17 | {11, &IProcessWindingController::OpenCallingLibraryApplet, "OpenCallingLibraryApplet"}, | ||
| 18 | {21, nullptr, "PushContext"}, | ||
| 19 | {22, nullptr, "PopContext"}, | ||
| 20 | {23, nullptr, "CancelWindingReservation"}, | ||
| 21 | {30, nullptr, "WindAndDoReserved"}, | ||
| 22 | {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, | ||
| 23 | {41, nullptr, "ReserveToStartAndWait"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | |||
| 30 | IProcessWindingController::~IProcessWindingController() = default; | ||
| 31 | |||
| 32 | void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) { | ||
| 33 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 34 | |||
| 35 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 36 | rb.Push(ResultSuccess); | ||
| 37 | rb.PushRaw(applet->launch_reason); | ||
| 38 | } | ||
| 39 | |||
| 40 | void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) { | ||
| 41 | const auto caller_applet = applet->caller_applet.lock(); | ||
| 42 | if (caller_applet == nullptr) { | ||
| 43 | LOG_ERROR(Service_AM, "No calling applet available"); | ||
| 44 | |||
| 45 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 46 | rb.Push(ResultUnknown); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | |||
| 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 51 | rb.Push(ResultSuccess); | ||
| 52 | rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_broker, | ||
| 53 | caller_applet); | ||
| 54 | } | ||
| 55 | |||
| 56 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp deleted file mode 100644 index 65e249c0c..000000000 --- a/src/core/hle/service/am/self_controller.cpp +++ /dev/null | |||
| @@ -1,470 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/result.h" | ||
| 6 | #include "core/hle/service/am/am_results.h" | ||
| 7 | #include "core/hle/service/am/frontend/applets.h" | ||
| 8 | #include "core/hle/service/am/self_controller.h" | ||
| 9 | #include "core/hle/service/caps/caps_su.h" | ||
| 10 | #include "core/hle/service/hle_ipc.h" | ||
| 11 | #include "core/hle/service/ipc_helpers.h" | ||
| 12 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 13 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 14 | #include "core/hle/service/sm/sm.h" | ||
| 15 | #include "core/hle/service/vi/vi_results.h" | ||
| 16 | |||
| 17 | namespace Service::AM { | ||
| 18 | |||
| 19 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_, | ||
| 20 | Nvnflinger::Nvnflinger& nvnflinger_) | ||
| 21 | : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, applet{std::move( | ||
| 22 | applet_)} { | ||
| 23 | // clang-format off | ||
| 24 | static const FunctionInfo functions[] = { | ||
| 25 | {0, &ISelfController::Exit, "Exit"}, | ||
| 26 | {1, &ISelfController::LockExit, "LockExit"}, | ||
| 27 | {2, &ISelfController::UnlockExit, "UnlockExit"}, | ||
| 28 | {3, &ISelfController::EnterFatalSection, "EnterFatalSection"}, | ||
| 29 | {4, &ISelfController::LeaveFatalSection, "LeaveFatalSection"}, | ||
| 30 | {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"}, | ||
| 31 | {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"}, | ||
| 32 | {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"}, | ||
| 33 | {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"}, | ||
| 34 | {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"}, | ||
| 35 | {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"}, | ||
| 36 | {15, &ISelfController::SetScreenShotAppletIdentityInfo, "SetScreenShotAppletIdentityInfo"}, | ||
| 37 | {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"}, | ||
| 38 | {17, nullptr, "SetControllerFirmwareUpdateSection"}, | ||
| 39 | {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"}, | ||
| 40 | {19, &ISelfController::SetAlbumImageOrientation, "SetAlbumImageOrientation"}, | ||
| 41 | {20, nullptr, "SetDesirableKeyboardLayout"}, | ||
| 42 | {21, nullptr, "GetScreenShotProgramId"}, | ||
| 43 | {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, | ||
| 44 | {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"}, | ||
| 45 | {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"}, | ||
| 46 | {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"}, | ||
| 47 | {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"}, | ||
| 48 | {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, | ||
| 49 | {46, nullptr, "SetRecordingLayerCompositionEnabled"}, | ||
| 50 | {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, | ||
| 51 | {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"}, | ||
| 52 | {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, | ||
| 53 | {61, &ISelfController::SetMediaPlaybackState, "SetMediaPlaybackState"}, | ||
| 54 | {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"}, | ||
| 55 | {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"}, | ||
| 56 | {64, nullptr, "SetInputDetectionSourceSet"}, | ||
| 57 | {65, &ISelfController::ReportUserIsActive, "ReportUserIsActive"}, | ||
| 58 | {66, nullptr, "GetCurrentIlluminance"}, | ||
| 59 | {67, nullptr, "IsIlluminanceAvailable"}, | ||
| 60 | {68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"}, | ||
| 61 | {69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"}, | ||
| 62 | {70, nullptr, "ReportMultimediaError"}, | ||
| 63 | {71, nullptr, "GetCurrentIlluminanceEx"}, | ||
| 64 | {72, nullptr, "SetInputDetectionPolicy"}, | ||
| 65 | {80, nullptr, "SetWirelessPriorityMode"}, | ||
| 66 | {90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"}, | ||
| 67 | {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"}, | ||
| 68 | {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"}, | ||
| 69 | {110, nullptr, "SetApplicationAlbumUserData"}, | ||
| 70 | {120, &ISelfController::SaveCurrentScreenshot, "SaveCurrentScreenshot"}, | ||
| 71 | {130, &ISelfController::SetRecordVolumeMuted, "SetRecordVolumeMuted"}, | ||
| 72 | {1000, nullptr, "GetDebugStorageChannel"}, | ||
| 73 | }; | ||
| 74 | // clang-format on | ||
| 75 | |||
| 76 | RegisterHandlers(functions); | ||
| 77 | } | ||
| 78 | |||
| 79 | ISelfController::~ISelfController() = default; | ||
| 80 | |||
| 81 | void ISelfController::Exit(HLERequestContext& ctx) { | ||
| 82 | LOG_DEBUG(Service_AM, "called"); | ||
| 83 | |||
| 84 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 85 | rb.Push(ResultSuccess); | ||
| 86 | |||
| 87 | // TODO | ||
| 88 | system.Exit(); | ||
| 89 | } | ||
| 90 | |||
| 91 | void ISelfController::LockExit(HLERequestContext& ctx) { | ||
| 92 | LOG_DEBUG(Service_AM, "called"); | ||
| 93 | |||
| 94 | system.SetExitLocked(true); | ||
| 95 | |||
| 96 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 97 | rb.Push(ResultSuccess); | ||
| 98 | } | ||
| 99 | |||
| 100 | void ISelfController::UnlockExit(HLERequestContext& ctx) { | ||
| 101 | LOG_DEBUG(Service_AM, "called"); | ||
| 102 | |||
| 103 | system.SetExitLocked(false); | ||
| 104 | |||
| 105 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 106 | rb.Push(ResultSuccess); | ||
| 107 | |||
| 108 | if (system.GetExitRequested()) { | ||
| 109 | system.Exit(); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | void ISelfController::EnterFatalSection(HLERequestContext& ctx) { | ||
| 114 | |||
| 115 | std::scoped_lock lk{applet->lock}; | ||
| 116 | applet->fatal_section_count++; | ||
| 117 | LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", applet->fatal_section_count); | ||
| 118 | |||
| 119 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 120 | rb.Push(ResultSuccess); | ||
| 121 | } | ||
| 122 | |||
| 123 | void ISelfController::LeaveFatalSection(HLERequestContext& ctx) { | ||
| 124 | LOG_DEBUG(Service_AM, "called."); | ||
| 125 | |||
| 126 | // Entry and exit of fatal sections must be balanced. | ||
| 127 | std::scoped_lock lk{applet->lock}; | ||
| 128 | if (applet->fatal_section_count == 0) { | ||
| 129 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 130 | rb.Push(AM::ResultFatalSectionCountImbalance); | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | |||
| 134 | applet->fatal_section_count--; | ||
| 135 | |||
| 136 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 137 | rb.Push(ResultSuccess); | ||
| 138 | } | ||
| 139 | |||
| 140 | void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) { | ||
| 141 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 142 | |||
| 143 | applet->library_applet_launchable_event.Signal(); | ||
| 144 | |||
| 145 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 146 | rb.Push(ResultSuccess); | ||
| 147 | rb.PushCopyObjects(applet->library_applet_launchable_event.GetHandle()); | ||
| 148 | } | ||
| 149 | |||
| 150 | void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) { | ||
| 151 | IPC::RequestParser rp{ctx}; | ||
| 152 | const auto permission = rp.PopEnum<ScreenshotPermission>(); | ||
| 153 | LOG_DEBUG(Service_AM, "called, permission={}", permission); | ||
| 154 | |||
| 155 | std::scoped_lock lk{applet->lock}; | ||
| 156 | applet->screenshot_permission = permission; | ||
| 157 | |||
| 158 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 159 | rb.Push(ResultSuccess); | ||
| 160 | } | ||
| 161 | |||
| 162 | void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) { | ||
| 163 | IPC::RequestParser rp{ctx}; | ||
| 164 | |||
| 165 | const bool notification_enabled = rp.Pop<bool>(); | ||
| 166 | LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled); | ||
| 167 | |||
| 168 | std::scoped_lock lk{applet->lock}; | ||
| 169 | applet->operation_mode_changed_notification_enabled = notification_enabled; | ||
| 170 | |||
| 171 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 172 | rb.Push(ResultSuccess); | ||
| 173 | } | ||
| 174 | |||
| 175 | void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) { | ||
| 176 | IPC::RequestParser rp{ctx}; | ||
| 177 | |||
| 178 | const bool notification_enabled = rp.Pop<bool>(); | ||
| 179 | LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled); | ||
| 180 | |||
| 181 | std::scoped_lock lk{applet->lock}; | ||
| 182 | applet->performance_mode_changed_notification_enabled = notification_enabled; | ||
| 183 | |||
| 184 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 185 | rb.Push(ResultSuccess); | ||
| 186 | } | ||
| 187 | |||
| 188 | void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) { | ||
| 189 | IPC::RequestParser rp{ctx}; | ||
| 190 | |||
| 191 | const auto flags = rp.PopRaw<FocusHandlingMode>(); | ||
| 192 | |||
| 193 | LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}", | ||
| 194 | flags.unknown0, flags.unknown1, flags.unknown2); | ||
| 195 | |||
| 196 | std::scoped_lock lk{applet->lock}; | ||
| 197 | applet->focus_handling_mode = flags; | ||
| 198 | |||
| 199 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 200 | rb.Push(ResultSuccess); | ||
| 201 | } | ||
| 202 | |||
| 203 | void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) { | ||
| 204 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 205 | |||
| 206 | std::scoped_lock lk{applet->lock}; | ||
| 207 | applet->restart_message_enabled = true; | ||
| 208 | |||
| 209 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 210 | rb.Push(ResultSuccess); | ||
| 211 | } | ||
| 212 | |||
| 213 | void ISelfController::SetScreenShotAppletIdentityInfo(HLERequestContext& ctx) { | ||
| 214 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 215 | |||
| 216 | IPC::RequestParser rp{ctx}; | ||
| 217 | std::scoped_lock lk{applet->lock}; | ||
| 218 | applet->screen_shot_identity = rp.PopRaw<AppletIdentityInfo>(); | ||
| 219 | |||
| 220 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 221 | rb.Push(ResultSuccess); | ||
| 222 | } | ||
| 223 | |||
| 224 | void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) { | ||
| 225 | IPC::RequestParser rp{ctx}; | ||
| 226 | |||
| 227 | const bool enabled = rp.Pop<bool>(); | ||
| 228 | LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); | ||
| 229 | |||
| 230 | std::scoped_lock lk{applet->lock}; | ||
| 231 | ASSERT(applet->type == AppletType::Application); | ||
| 232 | applet->out_of_focus_suspension_enabled = enabled; | ||
| 233 | |||
| 234 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 235 | rb.Push(ResultSuccess); | ||
| 236 | } | ||
| 237 | |||
| 238 | void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) { | ||
| 239 | IPC::RequestParser rp{ctx}; | ||
| 240 | |||
| 241 | const auto orientation = rp.PopRaw<Capture::AlbumImageOrientation>(); | ||
| 242 | LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", static_cast<s32>(orientation)); | ||
| 243 | |||
| 244 | std::scoped_lock lk{applet->lock}; | ||
| 245 | applet->album_image_orientation = orientation; | ||
| 246 | |||
| 247 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 248 | rb.Push(ResultSuccess); | ||
| 249 | } | ||
| 250 | |||
| 251 | void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) { | ||
| 252 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 253 | |||
| 254 | u64 layer_id{}; | ||
| 255 | applet->managed_layer_holder.Initialize(&nvnflinger); | ||
| 256 | applet->managed_layer_holder.CreateManagedDisplayLayer(&layer_id); | ||
| 257 | |||
| 258 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 259 | rb.Push(ResultSuccess); | ||
| 260 | rb.Push(layer_id); | ||
| 261 | } | ||
| 262 | |||
| 263 | void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) { | ||
| 264 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 265 | |||
| 266 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 267 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); | ||
| 268 | } | ||
| 269 | |||
| 270 | void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) { | ||
| 271 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 272 | |||
| 273 | u64 buffer_id, layer_id; | ||
| 274 | applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id); | ||
| 275 | |||
| 276 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 277 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); | ||
| 278 | rb.Push<s64>(buffer_id); | ||
| 279 | rb.Push<s64>(layer_id); | ||
| 280 | } | ||
| 281 | |||
| 282 | void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) { | ||
| 283 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 284 | |||
| 285 | u64 buffer_id, layer_id; | ||
| 286 | applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id); | ||
| 287 | |||
| 288 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 289 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); | ||
| 290 | rb.Push<s64>(buffer_id); | ||
| 291 | } | ||
| 292 | |||
| 293 | Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) { | ||
| 294 | if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id, | ||
| 295 | applet->library_applet_mode)) { | ||
| 296 | return ResultSuccess; | ||
| 297 | } | ||
| 298 | |||
| 299 | return VI::ResultOperationFailed; | ||
| 300 | } | ||
| 301 | |||
| 302 | void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) { | ||
| 303 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 304 | |||
| 305 | u64 layer_id{}; | ||
| 306 | u64 recording_layer_id{}; | ||
| 307 | applet->managed_layer_holder.Initialize(&nvnflinger); | ||
| 308 | applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(&layer_id, &recording_layer_id); | ||
| 309 | |||
| 310 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 311 | rb.Push(ResultSuccess); | ||
| 312 | rb.Push(layer_id); | ||
| 313 | rb.Push(recording_layer_id); | ||
| 314 | } | ||
| 315 | |||
| 316 | void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) { | ||
| 317 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 318 | |||
| 319 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 320 | rb.Push(ResultSuccess); | ||
| 321 | } | ||
| 322 | |||
| 323 | void ISelfController::ApproveToDisplay(HLERequestContext& ctx) { | ||
| 324 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 325 | |||
| 326 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 327 | rb.Push(ResultSuccess); | ||
| 328 | } | ||
| 329 | |||
| 330 | void ISelfController::SetMediaPlaybackState(HLERequestContext& ctx) { | ||
| 331 | IPC::RequestParser rp{ctx}; | ||
| 332 | const u8 state = rp.Pop<u8>(); | ||
| 333 | |||
| 334 | LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state); | ||
| 335 | |||
| 336 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 337 | rb.Push(ResultSuccess); | ||
| 338 | } | ||
| 339 | |||
| 340 | void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { | ||
| 341 | IPC::RequestParser rp{ctx}; | ||
| 342 | |||
| 343 | const auto extension = rp.PopRaw<IdleTimeDetectionExtension>(); | ||
| 344 | LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", extension); | ||
| 345 | |||
| 346 | std::scoped_lock lk{applet->lock}; | ||
| 347 | applet->idle_time_detection_extension = extension; | ||
| 348 | |||
| 349 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 350 | rb.Push(ResultSuccess); | ||
| 351 | } | ||
| 352 | |||
| 353 | void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) { | ||
| 354 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 355 | |||
| 356 | std::scoped_lock lk{applet->lock}; | ||
| 357 | |||
| 358 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 359 | rb.Push(ResultSuccess); | ||
| 360 | rb.PushRaw<IdleTimeDetectionExtension>(applet->idle_time_detection_extension); | ||
| 361 | } | ||
| 362 | |||
| 363 | void ISelfController::ReportUserIsActive(HLERequestContext& ctx) { | ||
| 364 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 365 | |||
| 366 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 367 | rb.Push(ResultSuccess); | ||
| 368 | } | ||
| 369 | |||
| 370 | void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) { | ||
| 371 | IPC::RequestParser rp{ctx}; | ||
| 372 | |||
| 373 | std::scoped_lock lk{applet->lock}; | ||
| 374 | applet->auto_sleep_disabled = rp.Pop<bool>(); | ||
| 375 | |||
| 376 | // On the system itself, if the previous state of is_auto_sleep_disabled | ||
| 377 | // differed from the current value passed in, it'd signify the internal | ||
| 378 | // window manager to update (and also increment some statistics like update counts) | ||
| 379 | // | ||
| 380 | // It'd also indicate this change to an idle handling context. | ||
| 381 | // | ||
| 382 | // However, given we're emulating this behavior, most of this can be ignored | ||
| 383 | // and it's sufficient to simply set the member variable for querying via | ||
| 384 | // IsAutoSleepDisabled(). | ||
| 385 | |||
| 386 | LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", applet->auto_sleep_disabled); | ||
| 387 | |||
| 388 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 389 | rb.Push(ResultSuccess); | ||
| 390 | } | ||
| 391 | |||
| 392 | void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) { | ||
| 393 | LOG_DEBUG(Service_AM, "called."); | ||
| 394 | |||
| 395 | std::scoped_lock lk{applet->lock}; | ||
| 396 | |||
| 397 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 398 | rb.Push(ResultSuccess); | ||
| 399 | rb.Push(applet->auto_sleep_disabled); | ||
| 400 | } | ||
| 401 | |||
| 402 | void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) { | ||
| 403 | LOG_DEBUG(Service_AM, "called."); | ||
| 404 | |||
| 405 | std::scoped_lock lk{applet->lock}; | ||
| 406 | // This command returns the total number of system ticks since ISelfController creation | ||
| 407 | // where the game was suspended. Since Yuzu doesn't implement game suspension, this command | ||
| 408 | // can just always return 0 ticks. | ||
| 409 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 410 | rb.Push(ResultSuccess); | ||
| 411 | rb.Push<u64>(applet->suspended_ticks); | ||
| 412 | } | ||
| 413 | |||
| 414 | void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) { | ||
| 415 | LOG_DEBUG(Service_AM, "called."); | ||
| 416 | |||
| 417 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 418 | rb.Push(ResultSuccess); | ||
| 419 | rb.PushCopyObjects(applet->accumulated_suspended_tick_changed_event.GetHandle()); | ||
| 420 | } | ||
| 421 | |||
| 422 | void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) { | ||
| 423 | IPC::RequestParser rp{ctx}; | ||
| 424 | |||
| 425 | // This service call sets an internal flag whether a notification is shown when an image is | ||
| 426 | // captured. Currently we do not support capturing images via the capture button, so this can be | ||
| 427 | // stubbed for now. | ||
| 428 | const bool enabled = rp.Pop<bool>(); | ||
| 429 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
| 430 | |||
| 431 | std::scoped_lock lk{applet->lock}; | ||
| 432 | applet->album_image_taken_notification_enabled = enabled; | ||
| 433 | |||
| 434 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 435 | rb.Push(ResultSuccess); | ||
| 436 | } | ||
| 437 | |||
| 438 | void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) { | ||
| 439 | IPC::RequestParser rp{ctx}; | ||
| 440 | |||
| 441 | const auto report_option = rp.PopEnum<Capture::AlbumReportOption>(); | ||
| 442 | |||
| 443 | LOG_INFO(Service_AM, "called, report_option={}", report_option); | ||
| 444 | |||
| 445 | const auto screenshot_service = | ||
| 446 | system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>( | ||
| 447 | "caps:su"); | ||
| 448 | |||
| 449 | if (screenshot_service) { | ||
| 450 | screenshot_service->CaptureAndSaveScreenshot(report_option); | ||
| 451 | } | ||
| 452 | |||
| 453 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 454 | rb.Push(ResultSuccess); | ||
| 455 | } | ||
| 456 | |||
| 457 | void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) { | ||
| 458 | IPC::RequestParser rp{ctx}; | ||
| 459 | |||
| 460 | const auto enabled = rp.Pop<bool>(); | ||
| 461 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
| 462 | |||
| 463 | std::scoped_lock lk{applet->lock}; | ||
| 464 | applet->record_volume_muted = enabled; | ||
| 465 | |||
| 466 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 467 | rb.Push(ResultSuccess); | ||
| 468 | } | ||
| 469 | |||
| 470 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h deleted file mode 100644 index ab21a1881..000000000 --- a/src/core/hle/service/am/self_controller.h +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/hle_ipc.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | struct Applet; | ||
| 13 | |||
| 14 | class ISelfController final : public ServiceFramework<ISelfController> { | ||
| 15 | public: | ||
| 16 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_, | ||
| 17 | Nvnflinger::Nvnflinger& nvnflinger_); | ||
| 18 | ~ISelfController() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | void Exit(HLERequestContext& ctx); | ||
| 22 | void LockExit(HLERequestContext& ctx); | ||
| 23 | void UnlockExit(HLERequestContext& ctx); | ||
| 24 | void EnterFatalSection(HLERequestContext& ctx); | ||
| 25 | void LeaveFatalSection(HLERequestContext& ctx); | ||
| 26 | void GetLibraryAppletLaunchableEvent(HLERequestContext& ctx); | ||
| 27 | void SetScreenShotPermission(HLERequestContext& ctx); | ||
| 28 | void SetOperationModeChangedNotification(HLERequestContext& ctx); | ||
| 29 | void SetPerformanceModeChangedNotification(HLERequestContext& ctx); | ||
| 30 | void SetFocusHandlingMode(HLERequestContext& ctx); | ||
| 31 | void SetRestartMessageEnabled(HLERequestContext& ctx); | ||
| 32 | void SetScreenShotAppletIdentityInfo(HLERequestContext& ctx); | ||
| 33 | void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx); | ||
| 34 | void SetAlbumImageOrientation(HLERequestContext& ctx); | ||
| 35 | void IsSystemBufferSharingEnabled(HLERequestContext& ctx); | ||
| 36 | void GetSystemSharedBufferHandle(HLERequestContext& ctx); | ||
| 37 | void GetSystemSharedLayerHandle(HLERequestContext& ctx); | ||
| 38 | void CreateManagedDisplayLayer(HLERequestContext& ctx); | ||
| 39 | void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx); | ||
| 40 | void SetHandlesRequestToDisplay(HLERequestContext& ctx); | ||
| 41 | void ApproveToDisplay(HLERequestContext& ctx); | ||
| 42 | void SetMediaPlaybackState(HLERequestContext& ctx); | ||
| 43 | void SetIdleTimeDetectionExtension(HLERequestContext& ctx); | ||
| 44 | void GetIdleTimeDetectionExtension(HLERequestContext& ctx); | ||
| 45 | void ReportUserIsActive(HLERequestContext& ctx); | ||
| 46 | void SetAutoSleepDisabled(HLERequestContext& ctx); | ||
| 47 | void IsAutoSleepDisabled(HLERequestContext& ctx); | ||
| 48 | void GetAccumulatedSuspendedTickValue(HLERequestContext& ctx); | ||
| 49 | void GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx); | ||
| 50 | void SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx); | ||
| 51 | void SaveCurrentScreenshot(HLERequestContext& ctx); | ||
| 52 | void SetRecordVolumeMuted(HLERequestContext& ctx); | ||
| 53 | |||
| 54 | Result EnsureBufferSharingEnabled(Kernel::KProcess* process); | ||
| 55 | |||
| 56 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 57 | const std::shared_ptr<Applet> applet; | ||
| 58 | }; | ||
| 59 | |||
| 60 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp new file mode 100644 index 000000000..eebd90ba2 --- /dev/null +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" | ||
| 7 | #include "core/hle/service/am/service/library_applet_proxy.h" | ||
| 8 | #include "core/hle/service/am/service/system_applet_proxy.h" | ||
| 9 | #include "core/hle/service/cmif_serialization.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, | ||
| 14 | Nvnflinger::Nvnflinger& nvnflinger) | ||
| 15 | : ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, | ||
| 19 | {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"}, | ||
| 20 | {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"}, | ||
| 21 | {300, nullptr, "OpenOverlayAppletProxy"}, | ||
| 22 | {350, nullptr, "OpenSystemApplicationProxy"}, | ||
| 23 | {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, | ||
| 24 | {410, nullptr, "GetSystemAppletControllerForDebug"}, | ||
| 25 | {1000, nullptr, "GetDebugFunctions"}, | ||
| 26 | }; | ||
| 27 | // clang-format on | ||
| 28 | |||
| 29 | RegisterHandlers(functions); | ||
| 30 | } | ||
| 31 | |||
| 32 | IAllSystemAppletProxiesService::~IAllSystemAppletProxiesService() = default; | ||
| 33 | |||
| 34 | Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( | ||
| 35 | Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, ClientProcessId pid, | ||
| 36 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
| 37 | LOG_DEBUG(Service_AM, "called"); | ||
| 38 | |||
| 39 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | ||
| 40 | *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>( | ||
| 41 | system, applet, process_handle.Get(), m_nvnflinger); | ||
| 42 | R_SUCCEED(); | ||
| 43 | } else { | ||
| 44 | UNIMPLEMENTED(); | ||
| 45 | R_THROW(ResultUnknown); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( | ||
| 50 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
| 51 | InCopyHandle<Kernel::KProcess> process_handle, | ||
| 52 | InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute) { | ||
| 53 | LOG_DEBUG(Service_AM, "called"); | ||
| 54 | |||
| 55 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | ||
| 56 | *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>( | ||
| 57 | system, applet, process_handle.Get(), m_nvnflinger); | ||
| 58 | R_SUCCEED(); | ||
| 59 | } else { | ||
| 60 | UNIMPLEMENTED(); | ||
| 61 | R_THROW(ResultUnknown); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( | ||
| 66 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
| 67 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
| 68 | LOG_DEBUG(Service_AM, "called"); | ||
| 69 | |||
| 70 | AppletAttribute attribute{}; | ||
| 71 | R_RETURN( | ||
| 72 | this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute)); | ||
| 73 | } | ||
| 74 | |||
| 75 | std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( | ||
| 76 | ProcessId process_id) { | ||
| 77 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | ||
| 78 | } | ||
| 79 | |||
| 80 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h new file mode 100644 index 000000000..38b1ca2ea --- /dev/null +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service { | ||
| 10 | |||
| 11 | namespace Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace AM { | ||
| 16 | |||
| 17 | struct Applet; | ||
| 18 | struct AppletAttribute; | ||
| 19 | class ILibraryAppletProxy; | ||
| 20 | class ISystemAppletProxy; | ||
| 21 | |||
| 22 | class IAllSystemAppletProxiesService final | ||
| 23 | : public ServiceFramework<IAllSystemAppletProxiesService> { | ||
| 24 | public: | ||
| 25 | explicit IAllSystemAppletProxiesService(Core::System& system_, | ||
| 26 | Nvnflinger::Nvnflinger& nvnflinger); | ||
| 27 | ~IAllSystemAppletProxiesService() override; | ||
| 28 | |||
| 29 | private: | ||
| 30 | Result OpenSystemAppletProxy(Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, | ||
| 31 | ClientProcessId pid, | ||
| 32 | InCopyHandle<Kernel::KProcess> process_handle); | ||
| 33 | Result OpenLibraryAppletProxy(Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, | ||
| 34 | ClientProcessId pid, | ||
| 35 | InCopyHandle<Kernel::KProcess> process_handle, | ||
| 36 | InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute); | ||
| 37 | Result OpenLibraryAppletProxyOld( | ||
| 38 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
| 39 | InCopyHandle<Kernel::KProcess> process_handle); | ||
| 40 | |||
| 41 | private: | ||
| 42 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | ||
| 43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 44 | }; | ||
| 45 | |||
| 46 | } // namespace AM | ||
| 47 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/applet_common_functions.cpp b/src/core/hle/service/am/service/applet_common_functions.cpp index 130614ae5..0f29ab285 100644 --- a/src/core/hle/service/am/applet_common_functions.cpp +++ b/src/core/hle/service/am/service/applet_common_functions.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/applet.h" | 4 | #include "core/hle/service/am/applet.h" |
| 5 | #include "core/hle/service/am/applet_common_functions.h" | 5 | #include "core/hle/service/am/service/applet_common_functions.h" |
| 6 | #include "core/hle/service/ipc_helpers.h" | 6 | #include "core/hle/service/cmif_serialization.h" |
| 7 | 7 | ||
| 8 | namespace Service::AM { | 8 | namespace Service::AM { |
| 9 | 9 | ||
| @@ -20,18 +20,18 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, | |||
| 20 | {40, nullptr, "GetDisplayLogicalResolution"}, | 20 | {40, nullptr, "GetDisplayLogicalResolution"}, |
| 21 | {42, nullptr, "SetDisplayMagnification"}, | 21 | {42, nullptr, "SetDisplayMagnification"}, |
| 22 | {50, nullptr, "SetHomeButtonDoubleClickEnabled"}, | 22 | {50, nullptr, "SetHomeButtonDoubleClickEnabled"}, |
| 23 | {51, nullptr, "GetHomeButtonDoubleClickEnabled"}, | 23 | {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"}, |
| 24 | {52, nullptr, "IsHomeButtonShortPressedBlocked"}, | 24 | {52, nullptr, "IsHomeButtonShortPressedBlocked"}, |
| 25 | {60, nullptr, "IsVrModeCurtainRequired"}, | 25 | {60, nullptr, "IsVrModeCurtainRequired"}, |
| 26 | {61, nullptr, "IsSleepRequiredByHighTemperature"}, | 26 | {61, nullptr, "IsSleepRequiredByHighTemperature"}, |
| 27 | {62, nullptr, "IsSleepRequiredByLowBattery"}, | 27 | {62, nullptr, "IsSleepRequiredByLowBattery"}, |
| 28 | {70, &IAppletCommonFunctions::SetCpuBoostRequestPriority, "SetCpuBoostRequestPriority"}, | 28 | {70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"}, |
| 29 | {80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"}, | 29 | {80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"}, |
| 30 | {81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"}, | 30 | {81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"}, |
| 31 | {90, nullptr, "OpenNamedChannelAsParent"}, | 31 | {90, nullptr, "OpenNamedChannelAsParent"}, |
| 32 | {91, nullptr, "OpenNamedChannelAsChild"}, | 32 | {91, nullptr, "OpenNamedChannelAsChild"}, |
| 33 | {100, nullptr, "SetApplicationCoreUsageMode"}, | 33 | {100, nullptr, "SetApplicationCoreUsageMode"}, |
| 34 | {300, &IAppletCommonFunctions::GetCurrentApplicationId, "GetCurrentApplicationId"}, | 34 | {300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"}, |
| 35 | }; | 35 | }; |
| 36 | // clang-format on | 36 | // clang-format on |
| 37 | 37 | ||
| @@ -40,24 +40,24 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, | |||
| 40 | 40 | ||
| 41 | IAppletCommonFunctions::~IAppletCommonFunctions() = default; | 41 | IAppletCommonFunctions::~IAppletCommonFunctions() = default; |
| 42 | 42 | ||
| 43 | void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) { | 43 | Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled( |
| 44 | Out<bool> out_home_button_double_click_enabled) { | ||
| 44 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 45 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 46 | *out_home_button_double_click_enabled = false; | ||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 45 | 49 | ||
| 46 | IPC::RequestParser rp{ctx}; | 50 | Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) { |
| 47 | 51 | LOG_WARNING(Service_AM, "(STUBBED) called"); | |
| 48 | std::scoped_lock lk{applet->lock}; | 52 | std::scoped_lock lk{applet->lock}; |
| 49 | applet->cpu_boost_request_priority = rp.Pop<s32>(); | 53 | applet->cpu_boost_request_priority = priority; |
| 50 | 54 | R_SUCCEED(); | |
| 51 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | void IAppletCommonFunctions::GetCurrentApplicationId(HLERequestContext& ctx) { | 57 | Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_id) { |
| 56 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 58 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 57 | 59 | *out_application_id = system.GetApplicationProcessProgramID() & ~0xFFFULL; | |
| 58 | IPC::ResponseBuilder rb{ctx, 4}; | 60 | R_SUCCEED(); |
| 59 | rb.Push(ResultSuccess); | ||
| 60 | rb.Push<u64>(system.GetApplicationProcessProgramID() & ~0xFFFULL); | ||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | } // namespace Service::AM | 63 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_common_functions.h b/src/core/hle/service/am/service/applet_common_functions.h index b86adf5cb..4424fc83d 100644 --- a/src/core/hle/service/am/applet_common_functions.h +++ b/src/core/hle/service/am/service/applet_common_functions.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 6 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 7 | 8 | ||
| 8 | namespace Service::AM { | 9 | namespace Service::AM { |
| @@ -15,8 +16,9 @@ public: | |||
| 15 | ~IAppletCommonFunctions() override; | 16 | ~IAppletCommonFunctions() override; |
| 16 | 17 | ||
| 17 | private: | 18 | private: |
| 18 | void SetCpuBoostRequestPriority(HLERequestContext& ctx); | 19 | Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled); |
| 19 | void GetCurrentApplicationId(HLERequestContext& ctx); | 20 | Result SetCpuBoostRequestPriority(s32 priority); |
| 21 | Result GetCurrentApplicationId(Out<u64> out_application_id); | ||
| 20 | 22 | ||
| 21 | const std::shared_ptr<Applet> applet; | 23 | const std::shared_ptr<Applet> applet; |
| 22 | }; | 24 | }; |
diff --git a/src/core/hle/service/am/service/application_accessor.cpp b/src/core/hle/service/am/service/application_accessor.cpp new file mode 100644 index 000000000..6e7d110e8 --- /dev/null +++ b/src/core/hle/service/am/service/application_accessor.cpp | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/result.h" | ||
| 5 | #include "core/hle/service/am/am_types.h" | ||
| 6 | #include "core/hle/service/am/applet.h" | ||
| 7 | #include "core/hle/service/am/applet_data_broker.h" | ||
| 8 | #include "core/hle/service/am/applet_manager.h" | ||
| 9 | #include "core/hle/service/am/service/application_accessor.h" | ||
| 10 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
| 11 | #include "core/hle/service/am/service/storage.h" | ||
| 12 | #include "core/hle/service/cmif_serialization.h" | ||
| 13 | |||
| 14 | namespace Service::AM { | ||
| 15 | |||
| 16 | IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet) | ||
| 17 | : ServiceFramework{system_, "IApplicationAccessor"}, m_applet(std::move(applet)) { | ||
| 18 | // clang-format off | ||
| 19 | static const FunctionInfo functions[] = { | ||
| 20 | {0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, | ||
| 21 | {1, nullptr, "IsCompleted"}, | ||
| 22 | {10, D<&IApplicationAccessor::Start>, "Start"}, | ||
| 23 | {20, D<&IApplicationAccessor::RequestExit>, "RequestExit"}, | ||
| 24 | {25, D<&IApplicationAccessor::Terminate>, "Terminate"}, | ||
| 25 | {30, D<&IApplicationAccessor::GetResult>, "GetResult"}, | ||
| 26 | {101, D<&IApplicationAccessor::RequestForApplicationToGetForeground>, "RequestForApplicationToGetForeground"}, | ||
| 27 | {110, nullptr, "TerminateAllLibraryApplets"}, | ||
| 28 | {111, nullptr, "AreAnyLibraryAppletsLeft"}, | ||
| 29 | {112, D<&IApplicationAccessor::GetCurrentLibraryApplet>, "GetCurrentLibraryApplet"}, | ||
| 30 | {120, nullptr, "GetApplicationId"}, | ||
| 31 | {121, D<&IApplicationAccessor::PushLaunchParameter>, "PushLaunchParameter"}, | ||
| 32 | {122, D<&IApplicationAccessor::GetApplicationControlProperty>, "GetApplicationControlProperty"}, | ||
| 33 | {123, nullptr, "GetApplicationLaunchProperty"}, | ||
| 34 | {124, nullptr, "GetApplicationLaunchRequestInfo"}, | ||
| 35 | {130, D<&IApplicationAccessor::SetUsers>, "SetUsers"}, | ||
| 36 | {131, D<&IApplicationAccessor::CheckRightsEnvironmentAvailable>, "CheckRightsEnvironmentAvailable"}, | ||
| 37 | {132, D<&IApplicationAccessor::GetNsRightsEnvironmentHandle>, "GetNsRightsEnvironmentHandle"}, | ||
| 38 | {140, nullptr, "GetDesirableUids"}, | ||
| 39 | {150, D<&IApplicationAccessor::ReportApplicationExitTimeout>, "ReportApplicationExitTimeout"}, | ||
| 40 | {160, nullptr, "SetApplicationAttribute"}, | ||
| 41 | {170, nullptr, "HasSaveDataAccessPermission"}, | ||
| 42 | {180, nullptr, "PushToFriendInvitationStorageChannel"}, | ||
| 43 | {190, nullptr, "PushToNotificationStorageChannel"}, | ||
| 44 | {200, nullptr, "RequestApplicationSoftReset"}, | ||
| 45 | {201, nullptr, "RestartApplicationTimer"}, | ||
| 46 | }; | ||
| 47 | // clang-format on | ||
| 48 | |||
| 49 | RegisterHandlers(functions); | ||
| 50 | } | ||
| 51 | |||
| 52 | IApplicationAccessor::~IApplicationAccessor() = default; | ||
| 53 | |||
| 54 | Result IApplicationAccessor::Start() { | ||
| 55 | LOG_INFO(Service_AM, "called"); | ||
| 56 | m_applet->process->Run(); | ||
| 57 | R_SUCCEED(); | ||
| 58 | } | ||
| 59 | |||
| 60 | Result IApplicationAccessor::RequestExit() { | ||
| 61 | LOG_INFO(Service_AM, "called"); | ||
| 62 | m_applet->message_queue.RequestExit(); | ||
| 63 | R_SUCCEED(); | ||
| 64 | } | ||
| 65 | |||
| 66 | Result IApplicationAccessor::Terminate() { | ||
| 67 | LOG_INFO(Service_AM, "called"); | ||
| 68 | m_applet->process->Terminate(); | ||
| 69 | R_SUCCEED(); | ||
| 70 | } | ||
| 71 | |||
| 72 | Result IApplicationAccessor::GetResult() { | ||
| 73 | LOG_INFO(Service_AM, "called"); | ||
| 74 | R_SUCCEED(); | ||
| 75 | } | ||
| 76 | |||
| 77 | Result IApplicationAccessor::GetAppletStateChangedEvent( | ||
| 78 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 79 | LOG_INFO(Service_AM, "called"); | ||
| 80 | *out_event = m_applet->caller_applet_broker->GetStateChangedEvent().GetHandle(); | ||
| 81 | R_SUCCEED(); | ||
| 82 | } | ||
| 83 | |||
| 84 | Result IApplicationAccessor::PushLaunchParameter(LaunchParameterKind kind, | ||
| 85 | SharedPointer<IStorage> storage) { | ||
| 86 | LOG_INFO(Service_AM, "called, kind={}", kind); | ||
| 87 | |||
| 88 | switch (kind) { | ||
| 89 | case LaunchParameterKind::AccountPreselectedUser: | ||
| 90 | m_applet->preselected_user_launch_parameter.push_back(storage->GetData()); | ||
| 91 | R_SUCCEED(); | ||
| 92 | default: | ||
| 93 | R_THROW(ResultUnknown); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | Result IApplicationAccessor::GetApplicationControlProperty( | ||
| 98 | OutBuffer<BufferAttr_HipcMapAlias> out_control_property) { | ||
| 99 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 100 | R_THROW(ResultUnknown); | ||
| 101 | } | ||
| 102 | |||
| 103 | Result IApplicationAccessor::SetUsers(bool enable, | ||
| 104 | InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids) { | ||
| 105 | LOG_INFO(Service_AM, "called, enable={} user_id_count={}", enable, user_ids.size()); | ||
| 106 | R_SUCCEED(); | ||
| 107 | } | ||
| 108 | |||
| 109 | Result IApplicationAccessor::GetCurrentLibraryApplet( | ||
| 110 | Out<SharedPointer<ILibraryAppletAccessor>> out_accessor) { | ||
| 111 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 112 | *out_accessor = nullptr; | ||
| 113 | R_SUCCEED(); | ||
| 114 | } | ||
| 115 | |||
| 116 | Result IApplicationAccessor::RequestForApplicationToGetForeground() { | ||
| 117 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 118 | R_THROW(ResultUnknown); | ||
| 119 | } | ||
| 120 | |||
| 121 | Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) { | ||
| 122 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 123 | *out_is_available = true; | ||
| 124 | R_SUCCEED(); | ||
| 125 | } | ||
| 126 | |||
| 127 | Result IApplicationAccessor::GetNsRightsEnvironmentHandle(Out<u64> out_handle) { | ||
| 128 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 129 | *out_handle = 0xdeadbeef; | ||
| 130 | R_SUCCEED(); | ||
| 131 | } | ||
| 132 | |||
| 133 | Result IApplicationAccessor::ReportApplicationExitTimeout() { | ||
| 134 | LOG_ERROR(Service_AM, "called"); | ||
| 135 | R_SUCCEED(); | ||
| 136 | } | ||
| 137 | |||
| 138 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_accessor.h b/src/core/hle/service/am/service/application_accessor.h new file mode 100644 index 000000000..39a9b2153 --- /dev/null +++ b/src/core/hle/service/am/service/application_accessor.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/uuid.h" | ||
| 7 | #include "core/hle/service/am/am_types.h" | ||
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | struct Applet; | ||
| 14 | class ILibraryAppletAccessor; | ||
| 15 | class IStorage; | ||
| 16 | |||
| 17 | class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> { | ||
| 18 | public: | ||
| 19 | explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 20 | ~IApplicationAccessor() override; | ||
| 21 | |||
| 22 | private: | ||
| 23 | Result Start(); | ||
| 24 | Result RequestExit(); | ||
| 25 | Result Terminate(); | ||
| 26 | Result GetResult(); | ||
| 27 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 28 | Result PushLaunchParameter(LaunchParameterKind kind, SharedPointer<IStorage> storage); | ||
| 29 | Result GetApplicationControlProperty(OutBuffer<BufferAttr_HipcMapAlias> out_control_property); | ||
| 30 | Result SetUsers(bool enable, InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids); | ||
| 31 | Result GetCurrentLibraryApplet(Out<SharedPointer<ILibraryAppletAccessor>> out_accessor); | ||
| 32 | Result RequestForApplicationToGetForeground(); | ||
| 33 | Result CheckRightsEnvironmentAvailable(Out<bool> out_is_available); | ||
| 34 | Result GetNsRightsEnvironmentHandle(Out<u64> out_handle); | ||
| 35 | Result ReportApplicationExitTimeout(); | ||
| 36 | |||
| 37 | const std::shared_ptr<Applet> m_applet; | ||
| 38 | }; | ||
| 39 | |||
| 40 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp index 79ea045a3..568bb0122 100644 --- a/src/core/hle/service/am/application_creator.cpp +++ b/src/core/hle/service/am/service/application_creator.cpp | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/application_creator.h" | 4 | #include "core/hle/service/am/am_types.h" |
| 5 | #include "core/hle/service/ipc_helpers.h" | 5 | #include "core/hle/service/am/applet.h" |
| 6 | #include "core/hle/service/am/applet_manager.h" | ||
| 7 | #include "core/hle/service/am/service/application_accessor.h" | ||
| 8 | #include "core/hle/service/am/service/application_creator.h" | ||
| 9 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | 10 | ||
| 7 | namespace Service::AM { | 11 | namespace Service::AM { |
| 8 | 12 | ||
| @@ -10,7 +14,7 @@ IApplicationCreator::IApplicationCreator(Core::System& system_) | |||
| 10 | : ServiceFramework{system_, "IApplicationCreator"} { | 14 | : ServiceFramework{system_, "IApplicationCreator"} { |
| 11 | // clang-format off | 15 | // clang-format off |
| 12 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 13 | {0, nullptr, "CreateApplication"}, | 17 | {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"}, |
| 14 | {1, nullptr, "PopLaunchRequestedApplication"}, | 18 | {1, nullptr, "PopLaunchRequestedApplication"}, |
| 15 | {10, nullptr, "CreateSystemApplication"}, | 19 | {10, nullptr, "CreateSystemApplication"}, |
| 16 | {100, nullptr, "PopFloatingApplicationForDevelopment"}, | 20 | {100, nullptr, "PopFloatingApplicationForDevelopment"}, |
| @@ -22,4 +26,10 @@ IApplicationCreator::IApplicationCreator(Core::System& system_) | |||
| 22 | 26 | ||
| 23 | IApplicationCreator::~IApplicationCreator() = default; | 27 | IApplicationCreator::~IApplicationCreator() = default; |
| 24 | 28 | ||
| 29 | Result IApplicationCreator::CreateApplication( | ||
| 30 | Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) { | ||
| 31 | LOG_ERROR(Service_NS, "called, application_id={:x}", application_id); | ||
| 32 | R_THROW(ResultUnknown); | ||
| 33 | } | ||
| 34 | |||
| 25 | } // namespace Service::AM | 35 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/application_creator.h b/src/core/hle/service/am/service/application_creator.h index 375a3c476..9f939ebf6 100644 --- a/src/core/hle/service/am/application_creator.h +++ b/src/core/hle/service/am/service/application_creator.h | |||
| @@ -3,14 +3,21 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 6 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 7 | 8 | ||
| 8 | namespace Service::AM { | 9 | namespace Service::AM { |
| 9 | 10 | ||
| 11 | class IApplicationAccessor; | ||
| 12 | struct Applet; | ||
| 13 | |||
| 10 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { | 14 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { |
| 11 | public: | 15 | public: |
| 12 | explicit IApplicationCreator(Core::System& system_); | 16 | explicit IApplicationCreator(Core::System& system_); |
| 13 | ~IApplicationCreator() override; | 17 | ~IApplicationCreator() override; |
| 18 | |||
| 19 | private: | ||
| 20 | Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id); | ||
| 14 | }; | 21 | }; |
| 15 | 22 | ||
| 16 | } // namespace Service::AM | 23 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp new file mode 100644 index 000000000..b788fddd4 --- /dev/null +++ b/src/core/hle/service/am/service/application_functions.cpp | |||
| @@ -0,0 +1,465 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "common/uuid.h" | ||
| 6 | #include "core/file_sys/control_metadata.h" | ||
| 7 | #include "core/file_sys/patch_manager.h" | ||
| 8 | #include "core/file_sys/registered_cache.h" | ||
| 9 | #include "core/file_sys/savedata_factory.h" | ||
| 10 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 11 | #include "core/hle/service/am/am_results.h" | ||
| 12 | #include "core/hle/service/am/applet.h" | ||
| 13 | #include "core/hle/service/am/service/application_functions.h" | ||
| 14 | #include "core/hle/service/am/service/storage.h" | ||
| 15 | #include "core/hle/service/cmif_serialization.h" | ||
| 16 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 17 | #include "core/hle/service/filesystem/save_data_controller.h" | ||
| 18 | #include "core/hle/service/ns/ns.h" | ||
| 19 | #include "core/hle/service/sm/sm.h" | ||
| 20 | |||
| 21 | namespace Service::AM { | ||
| 22 | |||
| 23 | IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet) | ||
| 24 | : ServiceFramework{system_, "IApplicationFunctions"}, m_applet{std::move(applet)} { | ||
| 25 | // clang-format off | ||
| 26 | static const FunctionInfo functions[] = { | ||
| 27 | {1, D<&IApplicationFunctions::PopLaunchParameter>, "PopLaunchParameter"}, | ||
| 28 | {10, nullptr, "CreateApplicationAndPushAndRequestToStart"}, | ||
| 29 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, | ||
| 30 | {12, nullptr, "CreateApplicationAndRequestToStart"}, | ||
| 31 | {13, nullptr, "CreateApplicationAndRequestToStartForQuest"}, | ||
| 32 | {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"}, | ||
| 33 | {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"}, | ||
| 34 | {20, D<&IApplicationFunctions::EnsureSaveData>, "EnsureSaveData"}, | ||
| 35 | {21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"}, | ||
| 36 | {22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"}, | ||
| 37 | {23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"}, | ||
| 38 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, | ||
| 39 | {25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"}, | ||
| 40 | {26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"}, | ||
| 41 | {27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"}, | ||
| 42 | {28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"}, | ||
| 43 | {29, nullptr, "GetCacheStorageMax"}, | ||
| 44 | {30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"}, | ||
| 45 | {31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"}, | ||
| 46 | {32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"}, | ||
| 47 | {33, D<&IApplicationFunctions::EndBlockingHomeButton>, "EndBlockingHomeButton"}, | ||
| 48 | {34, nullptr, "SelectApplicationLicense"}, | ||
| 49 | {35, nullptr, "GetDeviceSaveDataSizeMax"}, | ||
| 50 | {36, nullptr, "GetLimitedApplicationLicense"}, | ||
| 51 | {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, | ||
| 52 | {40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"}, | ||
| 53 | {50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"}, | ||
| 54 | {60, nullptr, "SetMediaPlaybackStateForApplication"}, | ||
| 55 | {65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"}, | ||
| 56 | {66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"}, | ||
| 57 | {67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"}, | ||
| 58 | {68, nullptr, "RequestFlushGamePlayingMovieForDebug"}, | ||
| 59 | {70, nullptr, "RequestToShutdown"}, | ||
| 60 | {71, nullptr, "RequestToReboot"}, | ||
| 61 | {72, nullptr, "RequestToSleep"}, | ||
| 62 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, | ||
| 63 | {90, D<&IApplicationFunctions::EnableApplicationCrashReport>, "EnableApplicationCrashReport"}, | ||
| 64 | {100, D<&IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer>, "InitializeApplicationCopyrightFrameBuffer"}, | ||
| 65 | {101, D<&IApplicationFunctions::SetApplicationCopyrightImage>, "SetApplicationCopyrightImage"}, | ||
| 66 | {102, D<&IApplicationFunctions::SetApplicationCopyrightVisibility>, "SetApplicationCopyrightVisibility"}, | ||
| 67 | {110, D<&IApplicationFunctions::QueryApplicationPlayStatistics>, "QueryApplicationPlayStatistics"}, | ||
| 68 | {111, D<&IApplicationFunctions::QueryApplicationPlayStatisticsByUid>, "QueryApplicationPlayStatisticsByUid"}, | ||
| 69 | {120, D<&IApplicationFunctions::ExecuteProgram>, "ExecuteProgram"}, | ||
| 70 | {121, D<&IApplicationFunctions::ClearUserChannel>, "ClearUserChannel"}, | ||
| 71 | {122, D<&IApplicationFunctions::UnpopToUserChannel>, "UnpopToUserChannel"}, | ||
| 72 | {123, D<&IApplicationFunctions::GetPreviousProgramIndex>, "GetPreviousProgramIndex"}, | ||
| 73 | {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||
| 74 | {130, D<&IApplicationFunctions::GetGpuErrorDetectedSystemEvent>, "GetGpuErrorDetectedSystemEvent"}, | ||
| 75 | {131, nullptr, "SetDelayTimeToAbortOnGpuError"}, | ||
| 76 | {140, D<&IApplicationFunctions::GetFriendInvitationStorageChannelEvent>, "GetFriendInvitationStorageChannelEvent"}, | ||
| 77 | {141, D<&IApplicationFunctions::TryPopFromFriendInvitationStorageChannel>, "TryPopFromFriendInvitationStorageChannel"}, | ||
| 78 | {150, D<&IApplicationFunctions::GetNotificationStorageChannelEvent>, "GetNotificationStorageChannelEvent"}, | ||
| 79 | {151, nullptr, "TryPopFromNotificationStorageChannel"}, | ||
| 80 | {160, D<&IApplicationFunctions::GetHealthWarningDisappearedSystemEvent>, "GetHealthWarningDisappearedSystemEvent"}, | ||
| 81 | {170, nullptr, "SetHdcpAuthenticationActivated"}, | ||
| 82 | {180, nullptr, "GetLaunchRequiredVersion"}, | ||
| 83 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
| 84 | {190, nullptr, "SendServerMaintenanceOverlayNotification"}, | ||
| 85 | {200, nullptr, "GetLastApplicationExitReason"}, | ||
| 86 | {500, nullptr, "StartContinuousRecordingFlushForDebug"}, | ||
| 87 | {1000, nullptr, "CreateMovieMaker"}, | ||
| 88 | {1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"}, | ||
| 89 | }; | ||
| 90 | // clang-format on | ||
| 91 | |||
| 92 | RegisterHandlers(functions); | ||
| 93 | } | ||
| 94 | |||
| 95 | IApplicationFunctions::~IApplicationFunctions() = default; | ||
| 96 | |||
| 97 | Result IApplicationFunctions::PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage, | ||
| 98 | LaunchParameterKind launch_parameter_kind) { | ||
| 99 | LOG_INFO(Service_AM, "called, kind={}", launch_parameter_kind); | ||
| 100 | |||
| 101 | std::scoped_lock lk{m_applet->lock}; | ||
| 102 | |||
| 103 | auto& channel = launch_parameter_kind == LaunchParameterKind::UserChannel | ||
| 104 | ? m_applet->user_channel_launch_parameter | ||
| 105 | : m_applet->preselected_user_launch_parameter; | ||
| 106 | |||
| 107 | if (channel.empty()) { | ||
| 108 | LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", | ||
| 109 | launch_parameter_kind); | ||
| 110 | R_THROW(AM::ResultNoDataInChannel); | ||
| 111 | } | ||
| 112 | |||
| 113 | auto data = channel.back(); | ||
| 114 | channel.pop_back(); | ||
| 115 | |||
| 116 | *out_storage = std::make_shared<IStorage>(system, std::move(data)); | ||
| 117 | R_SUCCEED(); | ||
| 118 | } | ||
| 119 | |||
| 120 | Result IApplicationFunctions::EnsureSaveData(Out<u64> out_size, Common::UUID user_id) { | ||
| 121 | LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString()); | ||
| 122 | |||
| 123 | FileSys::SaveDataAttribute attribute{}; | ||
| 124 | attribute.title_id = m_applet->program_id; | ||
| 125 | attribute.user_id = user_id.AsU128(); | ||
| 126 | attribute.type = FileSys::SaveDataType::SaveData; | ||
| 127 | |||
| 128 | FileSys::VirtualDir save_data{}; | ||
| 129 | R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( | ||
| 130 | &save_data, FileSys::SaveDataSpaceId::NandUser, attribute)); | ||
| 131 | |||
| 132 | *out_size = 0; | ||
| 133 | R_SUCCEED(); | ||
| 134 | } | ||
| 135 | |||
| 136 | Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) { | ||
| 137 | // FIXME: all of this stuff belongs to ns | ||
| 138 | // TODO(bunnei): This should be configurable | ||
| 139 | LOG_DEBUG(Service_AM, "called"); | ||
| 140 | |||
| 141 | // Get supported languages from NACP, if possible | ||
| 142 | // Default to 0 (all languages supported) | ||
| 143 | u32 supported_languages = 0; | ||
| 144 | |||
| 145 | const auto res = [this] { | ||
| 146 | const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(), | ||
| 147 | system.GetContentProvider()}; | ||
| 148 | auto metadata = pm.GetControlMetadata(); | ||
| 149 | if (metadata.first != nullptr) { | ||
| 150 | return metadata; | ||
| 151 | } | ||
| 152 | |||
| 153 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id), | ||
| 154 | system.GetFileSystemController(), | ||
| 155 | system.GetContentProvider()}; | ||
| 156 | return pm_update.GetControlMetadata(); | ||
| 157 | }(); | ||
| 158 | |||
| 159 | if (res.first != nullptr) { | ||
| 160 | supported_languages = res.first->GetSupportedLanguages(); | ||
| 161 | } | ||
| 162 | |||
| 163 | // Call IApplicationManagerInterface implementation. | ||
| 164 | auto& service_manager = system.ServiceManager(); | ||
| 165 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | ||
| 166 | auto app_man = ns_am2->GetApplicationManagerInterface(); | ||
| 167 | |||
| 168 | // Get desired application language | ||
| 169 | u8 desired_language{}; | ||
| 170 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); | ||
| 171 | |||
| 172 | // Convert to settings language code. | ||
| 173 | R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(out_language_code, desired_language)); | ||
| 174 | |||
| 175 | LOG_DEBUG(Service_AM, "got desired_language={:016X}", *out_language_code); | ||
| 176 | R_SUCCEED(); | ||
| 177 | } | ||
| 178 | |||
| 179 | Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { | ||
| 180 | LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(), | ||
| 181 | static_cast<u32>(terminate_result.GetModule()) + 2000, | ||
| 182 | terminate_result.GetDescription()); | ||
| 183 | |||
| 184 | std::scoped_lock lk{m_applet->lock}; | ||
| 185 | m_applet->terminate_result = terminate_result; | ||
| 186 | |||
| 187 | R_SUCCEED(); | ||
| 188 | } | ||
| 189 | |||
| 190 | Result IApplicationFunctions::GetDisplayVersion(Out<DisplayVersion> out_display_version) { | ||
| 191 | LOG_DEBUG(Service_AM, "called"); | ||
| 192 | |||
| 193 | const auto res = [this] { | ||
| 194 | const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(), | ||
| 195 | system.GetContentProvider()}; | ||
| 196 | auto metadata = pm.GetControlMetadata(); | ||
| 197 | if (metadata.first != nullptr) { | ||
| 198 | return metadata; | ||
| 199 | } | ||
| 200 | |||
| 201 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id), | ||
| 202 | system.GetFileSystemController(), | ||
| 203 | system.GetContentProvider()}; | ||
| 204 | return pm_update.GetControlMetadata(); | ||
| 205 | }(); | ||
| 206 | |||
| 207 | if (res.first != nullptr) { | ||
| 208 | const auto& version = res.first->GetVersionString(); | ||
| 209 | std::memcpy(out_display_version->string.data(), version.data(), | ||
| 210 | std::min(version.size(), out_display_version->string.size())); | ||
| 211 | } else { | ||
| 212 | static constexpr char default_version[]{"1.0.0"}; | ||
| 213 | std::memcpy(out_display_version->string.data(), default_version, sizeof(default_version)); | ||
| 214 | } | ||
| 215 | |||
| 216 | out_display_version->string[out_display_version->string.size() - 1] = '\0'; | ||
| 217 | R_SUCCEED(); | ||
| 218 | } | ||
| 219 | |||
| 220 | Result IApplicationFunctions::ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type, | ||
| 221 | Common::UUID user_id, u64 normal_size, | ||
| 222 | u64 journal_size) { | ||
| 223 | LOG_DEBUG(Service_AM, "called with type={} user_id={} normal={:#x} journal={:#x}", | ||
| 224 | static_cast<u8>(type), user_id.FormattedString(), normal_size, journal_size); | ||
| 225 | |||
| 226 | system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize( | ||
| 227 | type, m_applet->program_id, user_id.AsU128(), {normal_size, journal_size}); | ||
| 228 | |||
| 229 | // The following value is used to indicate the amount of space remaining on failure | ||
| 230 | // due to running out of space. Since we always succeed, this should be 0. | ||
| 231 | *out_required_size = 0; | ||
| 232 | |||
| 233 | R_SUCCEED(); | ||
| 234 | } | ||
| 235 | |||
| 236 | Result IApplicationFunctions::GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size, | ||
| 237 | FileSys::SaveDataType type, Common::UUID user_id) { | ||
| 238 | LOG_DEBUG(Service_AM, "called with type={} user_id={}", type, user_id.FormattedString()); | ||
| 239 | |||
| 240 | const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize( | ||
| 241 | type, m_applet->program_id, user_id.AsU128()); | ||
| 242 | |||
| 243 | *out_normal_size = size.normal; | ||
| 244 | *out_journal_size = size.journal; | ||
| 245 | R_SUCCEED(); | ||
| 246 | } | ||
| 247 | |||
| 248 | Result IApplicationFunctions::CreateCacheStorage(Out<u32> out_target_media, | ||
| 249 | Out<u64> out_required_size, u16 index, | ||
| 250 | u64 normal_size, u64 journal_size) { | ||
| 251 | LOG_WARNING(Service_AM, "(STUBBED) called with index={} size={:#x} journal_size={:#x}", index, | ||
| 252 | normal_size, journal_size); | ||
| 253 | |||
| 254 | *out_target_media = 1; // Nand | ||
| 255 | *out_required_size = 0; | ||
| 256 | |||
| 257 | R_SUCCEED(); | ||
| 258 | } | ||
| 259 | |||
| 260 | Result IApplicationFunctions::GetSaveDataSizeMax(Out<u64> out_max_normal_size, | ||
| 261 | Out<u64> out_max_journal_size) { | ||
| 262 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 263 | |||
| 264 | *out_max_normal_size = 0xFFFFFFF; | ||
| 265 | *out_max_journal_size = 0xFFFFFFF; | ||
| 266 | |||
| 267 | R_SUCCEED(); | ||
| 268 | } | ||
| 269 | |||
| 270 | Result IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(s64 unused) { | ||
| 271 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 272 | |||
| 273 | std::scoped_lock lk{m_applet->lock}; | ||
| 274 | m_applet->home_button_long_pressed_blocked = true; | ||
| 275 | m_applet->home_button_short_pressed_blocked = true; | ||
| 276 | |||
| 277 | R_SUCCEED(); | ||
| 278 | } | ||
| 279 | |||
| 280 | Result IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed() { | ||
| 281 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 282 | |||
| 283 | std::scoped_lock lk{m_applet->lock}; | ||
| 284 | m_applet->home_button_long_pressed_blocked = false; | ||
| 285 | m_applet->home_button_short_pressed_blocked = false; | ||
| 286 | |||
| 287 | R_SUCCEED(); | ||
| 288 | } | ||
| 289 | |||
| 290 | Result IApplicationFunctions::BeginBlockingHomeButton(s64 timeout_ns) { | ||
| 291 | LOG_WARNING(Service_AM, "(STUBBED) called, timeout_ns={}", timeout_ns); | ||
| 292 | |||
| 293 | std::scoped_lock lk{m_applet->lock}; | ||
| 294 | m_applet->home_button_long_pressed_blocked = true; | ||
| 295 | m_applet->home_button_short_pressed_blocked = true; | ||
| 296 | m_applet->home_button_double_click_enabled = true; | ||
| 297 | |||
| 298 | R_SUCCEED(); | ||
| 299 | } | ||
| 300 | |||
| 301 | Result IApplicationFunctions::EndBlockingHomeButton() { | ||
| 302 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 303 | |||
| 304 | std::scoped_lock lk{m_applet->lock}; | ||
| 305 | m_applet->home_button_long_pressed_blocked = false; | ||
| 306 | m_applet->home_button_short_pressed_blocked = false; | ||
| 307 | m_applet->home_button_double_click_enabled = false; | ||
| 308 | |||
| 309 | R_SUCCEED(); | ||
| 310 | } | ||
| 311 | |||
| 312 | Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) { | ||
| 313 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 314 | *out_became_running = true; | ||
| 315 | R_SUCCEED(); | ||
| 316 | } | ||
| 317 | |||
| 318 | Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) { | ||
| 319 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 320 | *out_pseudo_device_id = {}; | ||
| 321 | R_SUCCEED(); | ||
| 322 | } | ||
| 323 | |||
| 324 | Result IApplicationFunctions::IsGamePlayRecordingSupported( | ||
| 325 | Out<bool> out_is_game_play_recording_supported) { | ||
| 326 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 327 | *out_is_game_play_recording_supported = m_applet->game_play_recording_supported; | ||
| 328 | R_SUCCEED(); | ||
| 329 | } | ||
| 330 | |||
| 331 | Result IApplicationFunctions::InitializeGamePlayRecording( | ||
| 332 | u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
| 333 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 334 | R_SUCCEED(); | ||
| 335 | } | ||
| 336 | |||
| 337 | Result IApplicationFunctions::SetGamePlayRecordingState( | ||
| 338 | GamePlayRecordingState game_play_recording_state) { | ||
| 339 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 340 | |||
| 341 | std::scoped_lock lk{m_applet->lock}; | ||
| 342 | m_applet->game_play_recording_state = game_play_recording_state; | ||
| 343 | |||
| 344 | R_SUCCEED(); | ||
| 345 | } | ||
| 346 | |||
| 347 | Result IApplicationFunctions::EnableApplicationCrashReport(bool enabled) { | ||
| 348 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 349 | |||
| 350 | std::scoped_lock lk{m_applet->lock}; | ||
| 351 | m_applet->application_crash_report_enabled = enabled; | ||
| 352 | |||
| 353 | R_SUCCEED(); | ||
| 354 | } | ||
| 355 | |||
| 356 | Result IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( | ||
| 357 | s32 width, s32 height, u64 transfer_memory_size, | ||
| 358 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
| 359 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 360 | R_SUCCEED(); | ||
| 361 | } | ||
| 362 | |||
| 363 | Result IApplicationFunctions::SetApplicationCopyrightImage( | ||
| 364 | s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode, | ||
| 365 | InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data) { | ||
| 366 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 367 | R_SUCCEED(); | ||
| 368 | } | ||
| 369 | |||
| 370 | Result IApplicationFunctions::SetApplicationCopyrightVisibility(bool visible) { | ||
| 371 | LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", visible); | ||
| 372 | R_SUCCEED(); | ||
| 373 | } | ||
| 374 | |||
| 375 | Result IApplicationFunctions::QueryApplicationPlayStatistics( | ||
| 376 | Out<s32> out_entries, | ||
| 377 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
| 378 | InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
| 379 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 380 | *out_entries = 0; | ||
| 381 | R_SUCCEED(); | ||
| 382 | } | ||
| 383 | |||
| 384 | Result IApplicationFunctions::QueryApplicationPlayStatisticsByUid( | ||
| 385 | Out<s32> out_entries, | ||
| 386 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
| 387 | Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
| 388 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 389 | *out_entries = 0; | ||
| 390 | R_SUCCEED(); | ||
| 391 | } | ||
| 392 | |||
| 393 | Result IApplicationFunctions::ExecuteProgram(ProgramSpecifyKind kind, u64 value) { | ||
| 394 | LOG_WARNING(Service_AM, "(STUBBED) called, kind={}, value={}", kind, value); | ||
| 395 | ASSERT(kind == ProgramSpecifyKind::ExecuteProgram || | ||
| 396 | kind == ProgramSpecifyKind::RestartProgram); | ||
| 397 | |||
| 398 | // Copy user channel ownership into the system so that it will be preserved | ||
| 399 | system.GetUserChannel() = m_applet->user_channel_launch_parameter; | ||
| 400 | system.ExecuteProgram(value); | ||
| 401 | R_SUCCEED(); | ||
| 402 | } | ||
| 403 | |||
| 404 | Result IApplicationFunctions::ClearUserChannel() { | ||
| 405 | LOG_DEBUG(Service_AM, "called"); | ||
| 406 | m_applet->user_channel_launch_parameter.clear(); | ||
| 407 | R_SUCCEED(); | ||
| 408 | } | ||
| 409 | |||
| 410 | Result IApplicationFunctions::UnpopToUserChannel(SharedPointer<IStorage> storage) { | ||
| 411 | LOG_DEBUG(Service_AM, "called"); | ||
| 412 | m_applet->user_channel_launch_parameter.push_back(storage->GetData()); | ||
| 413 | R_SUCCEED(); | ||
| 414 | } | ||
| 415 | |||
| 416 | Result IApplicationFunctions::GetPreviousProgramIndex(Out<s32> out_previous_program_index) { | ||
| 417 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 418 | *out_previous_program_index = m_applet->previous_program_index; | ||
| 419 | R_SUCCEED(); | ||
| 420 | } | ||
| 421 | |||
| 422 | Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent( | ||
| 423 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 424 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 425 | *out_event = m_applet->gpu_error_detected_event.GetHandle(); | ||
| 426 | R_SUCCEED(); | ||
| 427 | } | ||
| 428 | |||
| 429 | Result IApplicationFunctions::GetFriendInvitationStorageChannelEvent( | ||
| 430 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 431 | LOG_DEBUG(Service_AM, "called"); | ||
| 432 | *out_event = m_applet->friend_invitation_storage_channel_event.GetHandle(); | ||
| 433 | R_SUCCEED(); | ||
| 434 | } | ||
| 435 | |||
| 436 | Result IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( | ||
| 437 | Out<SharedPointer<IStorage>> out_storage) { | ||
| 438 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 439 | R_THROW(AM::ResultNoDataInChannel); | ||
| 440 | } | ||
| 441 | |||
| 442 | Result IApplicationFunctions::GetNotificationStorageChannelEvent( | ||
| 443 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 444 | LOG_DEBUG(Service_AM, "called"); | ||
| 445 | *out_event = m_applet->notification_storage_channel_event.GetHandle(); | ||
| 446 | R_SUCCEED(); | ||
| 447 | } | ||
| 448 | |||
| 449 | Result IApplicationFunctions::GetHealthWarningDisappearedSystemEvent( | ||
| 450 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 451 | LOG_DEBUG(Service_AM, "called"); | ||
| 452 | *out_event = m_applet->health_warning_disappeared_system_event.GetHandle(); | ||
| 453 | R_SUCCEED(); | ||
| 454 | } | ||
| 455 | |||
| 456 | Result IApplicationFunctions::PrepareForJit() { | ||
| 457 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 458 | |||
| 459 | std::scoped_lock lk{m_applet->lock}; | ||
| 460 | m_applet->jit_service_launched = true; | ||
| 461 | |||
| 462 | R_SUCCEED(); | ||
| 463 | } | ||
| 464 | |||
| 465 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h new file mode 100644 index 000000000..3548202f8 --- /dev/null +++ b/src/core/hle/service/am/service/application_functions.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/uuid.h" | ||
| 7 | #include "core/hle/service/am/am_types.h" | ||
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace FileSys { | ||
| 12 | enum class SaveDataType : u8; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | class KReadableEvent; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | struct Applet; | ||
| 22 | class IStorage; | ||
| 23 | |||
| 24 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | ||
| 25 | public: | ||
| 26 | explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 27 | ~IApplicationFunctions() override; | ||
| 28 | |||
| 29 | private: | ||
| 30 | Result PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage, | ||
| 31 | LaunchParameterKind launch_parameter_kind); | ||
| 32 | Result EnsureSaveData(Out<u64> out_size, Common::UUID user_id); | ||
| 33 | Result GetDesiredLanguage(Out<u64> out_language_code); | ||
| 34 | Result SetTerminateResult(Result terminate_result); | ||
| 35 | Result GetDisplayVersion(Out<DisplayVersion> out_display_version); | ||
| 36 | Result ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type, | ||
| 37 | Common::UUID user_id, u64 normal_size, u64 journal_size); | ||
| 38 | Result GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size, | ||
| 39 | FileSys::SaveDataType type, Common::UUID user_id); | ||
| 40 | Result CreateCacheStorage(Out<u32> out_target_media, Out<u64> out_required_size, u16 index, | ||
| 41 | u64 normal_size, u64 journal_size); | ||
| 42 | Result GetSaveDataSizeMax(Out<u64> out_max_normal_size, Out<u64> out_max_journal_size); | ||
| 43 | Result BeginBlockingHomeButtonShortAndLongPressed(s64 unused); | ||
| 44 | Result EndBlockingHomeButtonShortAndLongPressed(); | ||
| 45 | Result BeginBlockingHomeButton(s64 timeout_ns); | ||
| 46 | Result EndBlockingHomeButton(); | ||
| 47 | Result NotifyRunning(Out<bool> out_became_running); | ||
| 48 | Result GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id); | ||
| 49 | Result IsGamePlayRecordingSupported(Out<bool> out_is_game_play_recording_supported); | ||
| 50 | Result InitializeGamePlayRecording( | ||
| 51 | u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
| 52 | Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state); | ||
| 53 | Result EnableApplicationCrashReport(bool enabled); | ||
| 54 | Result InitializeApplicationCopyrightFrameBuffer( | ||
| 55 | s32 width, s32 height, u64 transfer_memory_size, | ||
| 56 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
| 57 | Result SetApplicationCopyrightImage( | ||
| 58 | s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode, | ||
| 59 | InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data); | ||
| 60 | Result SetApplicationCopyrightVisibility(bool visible); | ||
| 61 | Result QueryApplicationPlayStatistics( | ||
| 62 | Out<s32> out_entries, | ||
| 63 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
| 64 | InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
| 65 | Result QueryApplicationPlayStatisticsByUid( | ||
| 66 | Out<s32> out_entries, | ||
| 67 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
| 68 | Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
| 69 | Result ExecuteProgram(ProgramSpecifyKind kind, u64 value); | ||
| 70 | Result ClearUserChannel(); | ||
| 71 | Result UnpopToUserChannel(SharedPointer<IStorage> storage); | ||
| 72 | Result GetPreviousProgramIndex(Out<s32> out_previous_program_index); | ||
| 73 | Result GetGpuErrorDetectedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 74 | Result GetFriendInvitationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 75 | Result TryPopFromFriendInvitationStorageChannel(Out<SharedPointer<IStorage>> out_storage); | ||
| 76 | Result GetNotificationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 77 | Result GetHealthWarningDisappearedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 78 | Result PrepareForJit(); | ||
| 79 | |||
| 80 | const std::shared_ptr<Applet> m_applet; | ||
| 81 | }; | ||
| 82 | |||
| 83 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp new file mode 100644 index 000000000..776f4552b --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy.cpp | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/service/application_functions.h" | ||
| 6 | #include "core/hle/service/am/service/application_proxy.h" | ||
| 7 | #include "core/hle/service/am/service/audio_controller.h" | ||
| 8 | #include "core/hle/service/am/service/common_state_getter.h" | ||
| 9 | #include "core/hle/service/am/service/debug_functions.h" | ||
| 10 | #include "core/hle/service/am/service/display_controller.h" | ||
| 11 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
| 12 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
| 13 | #include "core/hle/service/am/service/self_controller.h" | ||
| 14 | #include "core/hle/service/am/service/window_controller.h" | ||
| 15 | #include "core/hle/service/cmif_serialization.h" | ||
| 16 | |||
| 17 | namespace Service::AM { | ||
| 18 | |||
| 19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 20 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | ||
| 21 | : ServiceFramework{system_, "IApplicationProxy"}, | ||
| 22 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 23 | // clang-format off | ||
| 24 | static const FunctionInfo functions[] = { | ||
| 25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
| 26 | {1, D<&IApplicationProxy::GetSelfController>, "GetSelfController"}, | ||
| 27 | {2, D<&IApplicationProxy::GetWindowController>, "GetWindowController"}, | ||
| 28 | {3, D<&IApplicationProxy::GetAudioController>, "GetAudioController"}, | ||
| 29 | {4, D<&IApplicationProxy::GetDisplayController>, "GetDisplayController"}, | ||
| 30 | {10, D<&IApplicationProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
| 31 | {11, D<&IApplicationProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
| 32 | {20, D<&IApplicationProxy::GetApplicationFunctions>, "GetApplicationFunctions"}, | ||
| 33 | {1000, D<&IApplicationProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
| 34 | }; | ||
| 35 | // clang-format on | ||
| 36 | |||
| 37 | RegisterHandlers(functions); | ||
| 38 | } | ||
| 39 | |||
| 40 | IApplicationProxy::~IApplicationProxy() = default; | ||
| 41 | |||
| 42 | Result IApplicationProxy::GetAudioController( | ||
| 43 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
| 44 | LOG_DEBUG(Service_AM, "called"); | ||
| 45 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
| 46 | R_SUCCEED(); | ||
| 47 | } | ||
| 48 | |||
| 49 | Result IApplicationProxy::GetDisplayController( | ||
| 50 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
| 51 | LOG_DEBUG(Service_AM, "called"); | ||
| 52 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
| 53 | R_SUCCEED(); | ||
| 54 | } | ||
| 55 | |||
| 56 | Result IApplicationProxy::GetProcessWindingController( | ||
| 57 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
| 58 | LOG_DEBUG(Service_AM, "called"); | ||
| 59 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
| 60 | R_SUCCEED(); | ||
| 61 | } | ||
| 62 | |||
| 63 | Result IApplicationProxy::GetDebugFunctions( | ||
| 64 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
| 65 | LOG_DEBUG(Service_AM, "called"); | ||
| 66 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
| 67 | R_SUCCEED(); | ||
| 68 | } | ||
| 69 | |||
| 70 | Result IApplicationProxy::GetWindowController( | ||
| 71 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
| 72 | LOG_DEBUG(Service_AM, "called"); | ||
| 73 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
| 74 | R_SUCCEED(); | ||
| 75 | } | ||
| 76 | |||
| 77 | Result IApplicationProxy::GetSelfController( | ||
| 78 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
| 79 | LOG_DEBUG(Service_AM, "called"); | ||
| 80 | *out_self_controller = | ||
| 81 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 82 | R_SUCCEED(); | ||
| 83 | } | ||
| 84 | |||
| 85 | Result IApplicationProxy::GetCommonStateGetter( | ||
| 86 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
| 87 | LOG_DEBUG(Service_AM, "called"); | ||
| 88 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
| 89 | R_SUCCEED(); | ||
| 90 | } | ||
| 91 | |||
| 92 | Result IApplicationProxy::GetLibraryAppletCreator( | ||
| 93 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
| 94 | LOG_DEBUG(Service_AM, "called"); | ||
| 95 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
| 96 | R_SUCCEED(); | ||
| 97 | } | ||
| 98 | |||
| 99 | Result IApplicationProxy::GetApplicationFunctions( | ||
| 100 | Out<SharedPointer<IApplicationFunctions>> out_application_functions) { | ||
| 101 | LOG_DEBUG(Service_AM, "called"); | ||
| 102 | *out_application_functions = std::make_shared<IApplicationFunctions>(system, m_applet); | ||
| 103 | R_SUCCEED(); | ||
| 104 | } | ||
| 105 | |||
| 106 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h new file mode 100644 index 000000000..1ebc593ba --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | class IAudioController; | ||
| 13 | class IApplicationFunctions; | ||
| 14 | class ICommonStateGetter; | ||
| 15 | class IDebugFunctions; | ||
| 16 | class IDisplayController; | ||
| 17 | class ILibraryAppletCreator; | ||
| 18 | class IProcessWindingController; | ||
| 19 | class ISelfController; | ||
| 20 | class IWindowController; | ||
| 21 | |||
| 22 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | ||
| 23 | public: | ||
| 24 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 25 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
| 26 | ~IApplicationProxy(); | ||
| 27 | |||
| 28 | private: | ||
| 29 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
| 30 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
| 31 | Result GetProcessWindingController( | ||
| 32 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
| 33 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
| 34 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
| 35 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
| 36 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
| 37 | Result GetLibraryAppletCreator( | ||
| 38 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
| 39 | Result GetApplicationFunctions( | ||
| 40 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); | ||
| 41 | |||
| 42 | private: | ||
| 43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 44 | Kernel::KProcess* const m_process; | ||
| 45 | const std::shared_ptr<Applet> m_applet; | ||
| 46 | }; | ||
| 47 | |||
| 48 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp new file mode 100644 index 000000000..36d4478df --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy_service.cpp | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/am/am.h" | ||
| 6 | #include "core/hle/service/am/applet_manager.h" | ||
| 7 | #include "core/hle/service/am/service/application_proxy.h" | ||
| 8 | #include "core/hle/service/am/service/application_proxy_service.h" | ||
| 9 | #include "core/hle/service/cmif_serialization.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | IApplicationProxyService::IApplicationProxyService(Core::System& system_, | ||
| 14 | Nvnflinger::Nvnflinger& nvnflinger) | ||
| 15 | : ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} { | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, | ||
| 18 | }; | ||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IApplicationProxyService::~IApplicationProxyService() = default; | ||
| 23 | |||
| 24 | Result IApplicationProxyService::OpenApplicationProxy( | ||
| 25 | Out<SharedPointer<IApplicationProxy>> out_application_proxy, ClientProcessId pid, | ||
| 26 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
| 27 | LOG_DEBUG(Service_AM, "called"); | ||
| 28 | |||
| 29 | if (const auto applet = this->GetAppletFromProcessId(pid)) { | ||
| 30 | *out_application_proxy = | ||
| 31 | std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger); | ||
| 32 | R_SUCCEED(); | ||
| 33 | } else { | ||
| 34 | UNIMPLEMENTED(); | ||
| 35 | R_THROW(ResultUnknown); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { | ||
| 40 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | ||
| 41 | } | ||
| 42 | |||
| 43 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h new file mode 100644 index 000000000..1c1d32d0b --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy_service.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service { | ||
| 10 | |||
| 11 | namespace Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace AM { | ||
| 16 | |||
| 17 | struct Applet; | ||
| 18 | class IApplicationProxy; | ||
| 19 | |||
| 20 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { | ||
| 21 | public: | ||
| 22 | explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); | ||
| 23 | ~IApplicationProxyService() override; | ||
| 24 | |||
| 25 | private: | ||
| 26 | Result OpenApplicationProxy(Out<SharedPointer<IApplicationProxy>> out_application_proxy, | ||
| 27 | ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle); | ||
| 28 | |||
| 29 | private: | ||
| 30 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | ||
| 31 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 32 | }; | ||
| 33 | |||
| 34 | } // namespace AM | ||
| 35 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/service/audio_controller.cpp b/src/core/hle/service/am/service/audio_controller.cpp new file mode 100644 index 000000000..ad731c7bd --- /dev/null +++ b/src/core/hle/service/am/service/audio_controller.cpp | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/audio_controller.h" | ||
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | IAudioController::IAudioController(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IAudioController"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, D<&IAudioController::SetExpectedMasterVolume>, "SetExpectedMasterVolume"}, | ||
| 14 | {1, D<&IAudioController::GetMainAppletExpectedMasterVolume>, "GetMainAppletExpectedMasterVolume"}, | ||
| 15 | {2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"}, | ||
| 16 | {3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"}, | ||
| 17 | {4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | |||
| 24 | IAudioController::~IAudioController() = default; | ||
| 25 | |||
| 26 | Result IAudioController::SetExpectedMasterVolume(f32 main_applet_volume, | ||
| 27 | f32 library_applet_volume) { | ||
| 28 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}", | ||
| 29 | main_applet_volume, library_applet_volume); | ||
| 30 | |||
| 31 | // Ensure the volume values remain within the 0-100% range | ||
| 32 | m_main_applet_volume = std::clamp(main_applet_volume, MinAllowedVolume, MaxAllowedVolume); | ||
| 33 | m_library_applet_volume = std::clamp(library_applet_volume, MinAllowedVolume, MaxAllowedVolume); | ||
| 34 | |||
| 35 | R_SUCCEED(); | ||
| 36 | } | ||
| 37 | |||
| 38 | Result IAudioController::GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume) { | ||
| 39 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}", m_main_applet_volume); | ||
| 40 | *out_main_applet_volume = m_main_applet_volume; | ||
| 41 | R_SUCCEED(); | ||
| 42 | } | ||
| 43 | |||
| 44 | Result IAudioController::GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume) { | ||
| 45 | LOG_DEBUG(Service_AM, "called. library_applet_volume={}", m_library_applet_volume); | ||
| 46 | *out_library_applet_volume = m_library_applet_volume; | ||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Result IAudioController::ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns) { | ||
| 51 | LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", volume, fade_time_ns); | ||
| 52 | |||
| 53 | m_main_applet_volume = std::clamp(volume, MinAllowedVolume, MaxAllowedVolume); | ||
| 54 | m_fade_time_ns = std::chrono::nanoseconds{fade_time_ns}; | ||
| 55 | |||
| 56 | R_SUCCEED(); | ||
| 57 | } | ||
| 58 | |||
| 59 | Result IAudioController::SetTransparentVolumeRate(f32 transparent_volume_rate) { | ||
| 60 | LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate); | ||
| 61 | |||
| 62 | // Clamp volume range to 0-100%. | ||
| 63 | m_transparent_volume_rate = | ||
| 64 | std::clamp(transparent_volume_rate, MinAllowedVolume, MaxAllowedVolume); | ||
| 65 | |||
| 66 | R_SUCCEED(); | ||
| 67 | } | ||
| 68 | |||
| 69 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/audio_controller.h b/src/core/hle/service/am/service/audio_controller.h new file mode 100644 index 000000000..4b0f3f9ae --- /dev/null +++ b/src/core/hle/service/am/service/audio_controller.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class IAudioController final : public ServiceFramework<IAudioController> { | ||
| 12 | public: | ||
| 13 | explicit IAudioController(Core::System& system_); | ||
| 14 | ~IAudioController() override; | ||
| 15 | |||
| 16 | private: | ||
| 17 | Result SetExpectedMasterVolume(f32 main_applet_volume, f32 library_applet_volume); | ||
| 18 | Result GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume); | ||
| 19 | Result GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume); | ||
| 20 | Result ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns); | ||
| 21 | Result SetTransparentVolumeRate(f32 transparent_volume_rate); | ||
| 22 | |||
| 23 | static constexpr float MinAllowedVolume = 0.0f; | ||
| 24 | static constexpr float MaxAllowedVolume = 1.0f; | ||
| 25 | |||
| 26 | float m_main_applet_volume{0.25f}; | ||
| 27 | float m_library_applet_volume{MaxAllowedVolume}; | ||
| 28 | float m_transparent_volume_rate{MinAllowedVolume}; | ||
| 29 | |||
| 30 | // Volume transition fade time in nanoseconds. | ||
| 31 | // e.g. If the main applet volume was 0% and was changed to 50% | ||
| 32 | // with a fade of 50ns, then over the course of 50ns, | ||
| 33 | // the volume will gradually fade up to 50% | ||
| 34 | std::chrono::nanoseconds m_fade_time_ns{0}; | ||
| 35 | }; | ||
| 36 | |||
| 37 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp new file mode 100644 index 000000000..12d7e8cb1 --- /dev/null +++ b/src/core/hle/service/am/service/common_state_getter.cpp | |||
| @@ -0,0 +1,277 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/hle/service/am/am_results.h" | ||
| 6 | #include "core/hle/service/am/applet.h" | ||
| 7 | #include "core/hle/service/am/service/common_state_getter.h" | ||
| 8 | #include "core/hle/service/am/service/lock_accessor.h" | ||
| 9 | #include "core/hle/service/apm/apm_interface.h" | ||
| 10 | #include "core/hle/service/cmif_serialization.h" | ||
| 11 | #include "core/hle/service/pm/pm.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | #include "core/hle/service/vi/vi.h" | ||
| 14 | |||
| 15 | namespace Service::AM { | ||
| 16 | |||
| 17 | ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet) | ||
| 18 | : ServiceFramework{system_, "ICommonStateGetter"}, m_applet{std::move(applet)} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, D<&ICommonStateGetter::GetEventHandle>, "GetEventHandle"}, | ||
| 22 | {1, D<&ICommonStateGetter::ReceiveMessage>, "ReceiveMessage"}, | ||
| 23 | {2, nullptr, "GetThisAppletKind"}, | ||
| 24 | {3, nullptr, "AllowToEnterSleep"}, | ||
| 25 | {4, nullptr, "DisallowToEnterSleep"}, | ||
| 26 | {5, D<&ICommonStateGetter::GetOperationMode>, "GetOperationMode"}, | ||
| 27 | {6, D<&ICommonStateGetter::GetPerformanceMode>, "GetPerformanceMode"}, | ||
| 28 | {7, nullptr, "GetCradleStatus"}, | ||
| 29 | {8, D<&ICommonStateGetter::GetBootMode>, "GetBootMode"}, | ||
| 30 | {9, D<&ICommonStateGetter::GetCurrentFocusState>, "GetCurrentFocusState"}, | ||
| 31 | {10, D<&ICommonStateGetter::RequestToAcquireSleepLock>, "RequestToAcquireSleepLock"}, | ||
| 32 | {11, nullptr, "ReleaseSleepLock"}, | ||
| 33 | {12, nullptr, "ReleaseSleepLockTransiently"}, | ||
| 34 | {13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"}, | ||
| 35 | {14, nullptr, "GetWakeupCount"}, | ||
| 36 | {20, nullptr, "PushToGeneralChannel"}, | ||
| 37 | {30, nullptr, "GetHomeButtonReaderLockAccessor"}, | ||
| 38 | {31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"}, | ||
| 39 | {32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"}, | ||
| 40 | {40, nullptr, "GetCradleFwVersion"}, | ||
| 41 | {50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled"}, | ||
| 42 | {51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled"}, | ||
| 43 | {52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled"}, | ||
| 44 | {53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx"}, | ||
| 45 | {54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx"}, | ||
| 46 | {55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection"}, | ||
| 47 | {59, nullptr, "SetVrPositionForDebug"}, | ||
| 48 | {60, D<&ICommonStateGetter::GetDefaultDisplayResolution>, "GetDefaultDisplayResolution"}, | ||
| 49 | {61, D<&ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent>, "GetDefaultDisplayResolutionChangeEvent"}, | ||
| 50 | {62, nullptr, "GetHdcpAuthenticationState"}, | ||
| 51 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, | ||
| 52 | {64, nullptr, "SetTvPowerStateMatchingMode"}, | ||
| 53 | {65, nullptr, "GetApplicationIdByContentActionName"}, | ||
| 54 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, | ||
| 55 | {67, nullptr, "CancelCpuBoostMode"}, | ||
| 56 | {68, D<&ICommonStateGetter::GetBuiltInDisplayType>, "GetBuiltInDisplayType"}, | ||
| 57 | {80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"}, | ||
| 58 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | ||
| 59 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | ||
| 60 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, | ||
| 61 | {110, nullptr, "OpenMyGpuErrorHandler"}, | ||
| 62 | {120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"}, | ||
| 63 | {200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"}, | ||
| 64 | {300, D<&ICommonStateGetter::GetSettingsPlatformRegion>, "GetSettingsPlatformRegion"}, | ||
| 65 | {400, nullptr, "ActivateMigrationService"}, | ||
| 66 | {401, nullptr, "DeactivateMigrationService"}, | ||
| 67 | {500, nullptr, "DisableSleepTillShutdown"}, | ||
| 68 | {501, nullptr, "SuppressDisablingSleepTemporarily"}, | ||
| 69 | {502, nullptr, "IsSleepEnabled"}, | ||
| 70 | {503, nullptr, "IsDisablingSleepSuppressed"}, | ||
| 71 | {900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, | ||
| 72 | }; | ||
| 73 | // clang-format on | ||
| 74 | |||
| 75 | RegisterHandlers(functions); | ||
| 76 | } | ||
| 77 | |||
| 78 | ICommonStateGetter::~ICommonStateGetter() = default; | ||
| 79 | |||
| 80 | Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 81 | LOG_DEBUG(Service_AM, "called"); | ||
| 82 | *out_event = &m_applet->message_queue.GetMessageReceiveEvent(); | ||
| 83 | R_SUCCEED(); | ||
| 84 | } | ||
| 85 | |||
| 86 | Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) { | ||
| 87 | LOG_DEBUG(Service_AM, "called"); | ||
| 88 | |||
| 89 | *out_applet_message = m_applet->message_queue.PopMessage(); | ||
| 90 | if (*out_applet_message == AppletMessage::None) { | ||
| 91 | LOG_ERROR(Service_AM, "Tried to pop message but none was available!"); | ||
| 92 | R_THROW(AM::ResultNoMessages); | ||
| 93 | } | ||
| 94 | |||
| 95 | R_SUCCEED(); | ||
| 96 | } | ||
| 97 | |||
| 98 | Result ICommonStateGetter::GetCurrentFocusState(Out<FocusState> out_focus_state) { | ||
| 99 | LOG_DEBUG(Service_AM, "called"); | ||
| 100 | |||
| 101 | std::scoped_lock lk{m_applet->lock}; | ||
| 102 | *out_focus_state = m_applet->focus_state; | ||
| 103 | |||
| 104 | R_SUCCEED(); | ||
| 105 | } | ||
| 106 | |||
| 107 | Result ICommonStateGetter::RequestToAcquireSleepLock() { | ||
| 108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 109 | |||
| 110 | // Sleep lock is acquired immediately. | ||
| 111 | m_applet->sleep_lock_event.Signal(); | ||
| 112 | R_SUCCEED(); | ||
| 113 | } | ||
| 114 | |||
| 115 | Result ICommonStateGetter::GetAcquiredSleepLockEvent( | ||
| 116 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 117 | LOG_WARNING(Service_AM, "called"); | ||
| 118 | *out_event = m_applet->sleep_lock_event.GetHandle(); | ||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | Result ICommonStateGetter::GetReaderLockAccessorEx( | ||
| 123 | Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) { | ||
| 124 | LOG_INFO(Service_AM, "called, button_type={}", button_type); | ||
| 125 | *out_lock_accessor = std::make_shared<ILockAccessor>(system); | ||
| 126 | R_SUCCEED(); | ||
| 127 | } | ||
| 128 | |||
| 129 | Result ICommonStateGetter::GetWriterLockAccessorEx( | ||
| 130 | Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) { | ||
| 131 | LOG_INFO(Service_AM, "called, button_type={}", button_type); | ||
| 132 | *out_lock_accessor = std::make_shared<ILockAccessor>(system); | ||
| 133 | R_SUCCEED(); | ||
| 134 | } | ||
| 135 | |||
| 136 | Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent( | ||
| 137 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 138 | LOG_DEBUG(Service_AM, "called"); | ||
| 139 | *out_event = &m_applet->message_queue.GetOperationModeChangedEvent(); | ||
| 140 | R_SUCCEED(); | ||
| 141 | } | ||
| 142 | |||
| 143 | Result ICommonStateGetter::GetOperationMode(Out<OperationMode> out_operation_mode) { | ||
| 144 | const bool use_docked_mode{Settings::IsDockedMode()}; | ||
| 145 | LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); | ||
| 146 | *out_operation_mode = use_docked_mode ? OperationMode::Docked : OperationMode::Handheld; | ||
| 147 | R_SUCCEED(); | ||
| 148 | } | ||
| 149 | |||
| 150 | Result ICommonStateGetter::GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode) { | ||
| 151 | LOG_DEBUG(Service_AM, "called"); | ||
| 152 | *out_performance_mode = system.GetAPMController().GetCurrentPerformanceMode(); | ||
| 153 | R_SUCCEED(); | ||
| 154 | } | ||
| 155 | |||
| 156 | Result ICommonStateGetter::GetBootMode(Out<PM::SystemBootMode> out_boot_mode) { | ||
| 157 | LOG_DEBUG(Service_AM, "called"); | ||
| 158 | *out_boot_mode = Service::PM::SystemBootMode::Normal; | ||
| 159 | R_SUCCEED(); | ||
| 160 | } | ||
| 161 | |||
| 162 | Result ICommonStateGetter::IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled) { | ||
| 163 | LOG_DEBUG(Service_AM, "called"); | ||
| 164 | |||
| 165 | std::scoped_lock lk{m_applet->lock}; | ||
| 166 | *out_is_vr_mode_enabled = m_applet->vr_mode_enabled; | ||
| 167 | R_SUCCEED(); | ||
| 168 | } | ||
| 169 | |||
| 170 | Result ICommonStateGetter::SetVrModeEnabled(bool is_vr_mode_enabled) { | ||
| 171 | std::scoped_lock lk{m_applet->lock}; | ||
| 172 | m_applet->vr_mode_enabled = is_vr_mode_enabled; | ||
| 173 | LOG_WARNING(Service_AM, "VR Mode is {}", m_applet->vr_mode_enabled ? "on" : "off"); | ||
| 174 | R_SUCCEED(); | ||
| 175 | } | ||
| 176 | |||
| 177 | Result ICommonStateGetter::SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled) { | ||
| 178 | LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}", | ||
| 179 | is_lcd_backlight_off_enabled); | ||
| 180 | R_SUCCEED(); | ||
| 181 | } | ||
| 182 | |||
| 183 | Result ICommonStateGetter::BeginVrModeEx() { | ||
| 184 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 185 | std::scoped_lock lk{m_applet->lock}; | ||
| 186 | m_applet->vr_mode_enabled = true; | ||
| 187 | R_SUCCEED(); | ||
| 188 | } | ||
| 189 | |||
| 190 | Result ICommonStateGetter::EndVrModeEx() { | ||
| 191 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 192 | std::scoped_lock lk{m_applet->lock}; | ||
| 193 | m_applet->vr_mode_enabled = false; | ||
| 194 | R_SUCCEED(); | ||
| 195 | } | ||
| 196 | |||
| 197 | Result ICommonStateGetter::IsInControllerFirmwareUpdateSection( | ||
| 198 | Out<bool> out_is_in_controller_firmware_update_section) { | ||
| 199 | LOG_INFO(Service_AM, "called"); | ||
| 200 | *out_is_in_controller_firmware_update_section = false; | ||
| 201 | R_SUCCEED(); | ||
| 202 | } | ||
| 203 | |||
| 204 | Result ICommonStateGetter::GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height) { | ||
| 205 | LOG_DEBUG(Service_AM, "called"); | ||
| 206 | |||
| 207 | if (Settings::IsDockedMode()) { | ||
| 208 | *out_width = static_cast<u32>(Service::VI::DisplayResolution::DockedWidth); | ||
| 209 | *out_height = static_cast<u32>(Service::VI::DisplayResolution::DockedHeight); | ||
| 210 | } else { | ||
| 211 | *out_width = static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth); | ||
| 212 | *out_height = static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight); | ||
| 213 | } | ||
| 214 | |||
| 215 | R_SUCCEED(); | ||
| 216 | } | ||
| 217 | |||
| 218 | void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) { | ||
| 219 | LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS"); | ||
| 220 | |||
| 221 | const auto& sm = system.ServiceManager(); | ||
| 222 | const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys"); | ||
| 223 | ASSERT(apm_sys != nullptr); | ||
| 224 | |||
| 225 | apm_sys->SetCpuBoostMode(ctx); | ||
| 226 | } | ||
| 227 | |||
| 228 | Result ICommonStateGetter::GetBuiltInDisplayType(Out<s32> out_display_type) { | ||
| 229 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 230 | *out_display_type = 0; | ||
| 231 | R_SUCCEED(); | ||
| 232 | } | ||
| 233 | |||
| 234 | Result ICommonStateGetter::PerformSystemButtonPressingIfInFocus(SystemButtonType type) { | ||
| 235 | LOG_WARNING(Service_AM, "(STUBBED) called, type={}", type); | ||
| 236 | R_SUCCEED(); | ||
| 237 | } | ||
| 238 | |||
| 239 | Result ICommonStateGetter::GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info) { | ||
| 240 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 241 | *out_operation_mode_system_info = 0; | ||
| 242 | R_SUCCEED(); | ||
| 243 | } | ||
| 244 | |||
| 245 | Result ICommonStateGetter::GetAppletLaunchedHistory( | ||
| 246 | Out<s32> out_count, OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids) { | ||
| 247 | LOG_INFO(Service_AM, "called"); | ||
| 248 | |||
| 249 | std::shared_ptr<Applet> current_applet = m_applet; | ||
| 250 | |||
| 251 | for (*out_count = 0; | ||
| 252 | *out_count < static_cast<s32>(out_applet_ids.size()) && current_applet != nullptr; | ||
| 253 | /* ... */) { | ||
| 254 | out_applet_ids[(*out_count)++] = current_applet->applet_id; | ||
| 255 | current_applet = current_applet->caller_applet.lock(); | ||
| 256 | } | ||
| 257 | |||
| 258 | R_SUCCEED(); | ||
| 259 | } | ||
| 260 | |||
| 261 | Result ICommonStateGetter::GetSettingsPlatformRegion( | ||
| 262 | Out<SysPlatformRegion> out_settings_platform_region) { | ||
| 263 | LOG_INFO(Service_AM, "called"); | ||
| 264 | *out_settings_platform_region = SysPlatformRegion::Global; | ||
| 265 | R_SUCCEED(); | ||
| 266 | } | ||
| 267 | |||
| 268 | Result ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled() { | ||
| 269 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 270 | |||
| 271 | std::scoped_lock lk{m_applet->lock}; | ||
| 272 | m_applet->request_exit_to_library_applet_at_execute_next_program_enabled = true; | ||
| 273 | |||
| 274 | R_SUCCEED(); | ||
| 275 | } | ||
| 276 | |||
| 277 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h new file mode 100644 index 000000000..5a8dca3d6 --- /dev/null +++ b/src/core/hle/service/am/service/common_state_getter.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/am/am_types.h" | ||
| 7 | #include "core/hle/service/apm/apm_controller.h" | ||
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 9 | #include "core/hle/service/pm/pm.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | class KReadableEvent; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::AM { | ||
| 17 | |||
| 18 | struct Applet; | ||
| 19 | class ILockAccessor; | ||
| 20 | |||
| 21 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { | ||
| 22 | public: | ||
| 23 | explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 24 | ~ICommonStateGetter() override; | ||
| 25 | |||
| 26 | private: | ||
| 27 | Result GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 28 | Result ReceiveMessage(Out<AppletMessage> out_applet_message); | ||
| 29 | Result GetCurrentFocusState(Out<FocusState> out_focus_state); | ||
| 30 | Result RequestToAcquireSleepLock(); | ||
| 31 | Result GetAcquiredSleepLockEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 32 | Result GetReaderLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor, | ||
| 33 | u32 button_type); | ||
| 34 | Result GetWriterLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor, | ||
| 35 | u32 button_type); | ||
| 36 | Result GetDefaultDisplayResolutionChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 37 | Result GetOperationMode(Out<OperationMode> out_operation_mode); | ||
| 38 | Result GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode); | ||
| 39 | Result GetBootMode(Out<PM::SystemBootMode> out_boot_mode); | ||
| 40 | Result IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled); | ||
| 41 | Result SetVrModeEnabled(bool is_vr_mode_enabled); | ||
| 42 | Result SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled); | ||
| 43 | Result BeginVrModeEx(); | ||
| 44 | Result EndVrModeEx(); | ||
| 45 | Result IsInControllerFirmwareUpdateSection( | ||
| 46 | Out<bool> out_is_in_controller_firmware_update_section); | ||
| 47 | Result GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height); | ||
| 48 | Result GetBuiltInDisplayType(Out<s32> out_display_type); | ||
| 49 | Result PerformSystemButtonPressingIfInFocus(SystemButtonType type); | ||
| 50 | Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info); | ||
| 51 | Result GetAppletLaunchedHistory(Out<s32> out_count, | ||
| 52 | OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); | ||
| 53 | Result GetSettingsPlatformRegion(Out<SysPlatformRegion> out_settings_platform_region); | ||
| 54 | Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); | ||
| 55 | |||
| 56 | void SetCpuBoostMode(HLERequestContext& ctx); | ||
| 57 | |||
| 58 | const std::shared_ptr<Applet> m_applet; | ||
| 59 | }; | ||
| 60 | |||
| 61 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.cpp b/src/core/hle/service/am/service/cradle_firmware_updater.cpp new file mode 100644 index 000000000..0a8af0858 --- /dev/null +++ b/src/core/hle/service/am/service/cradle_firmware_updater.cpp | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/cradle_firmware_updater.h" | ||
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | ICradleFirmwareUpdater::ICradleFirmwareUpdater(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ICradleFirmwareUpdater"}, | ||
| 11 | m_context{system, "ICradleFirmwareUpdater"}, m_cradle_device_info_event{m_context} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, D<&ICradleFirmwareUpdater::StartUpdate>, "StartUpdate"}, | ||
| 15 | {1, D<&ICradleFirmwareUpdater::FinishUpdate>, "FinishUpdate"}, | ||
| 16 | {2, D<&ICradleFirmwareUpdater::GetCradleDeviceInfo>, "GetCradleDeviceInfo"}, | ||
| 17 | {3, D<&ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent>, "GetCradleDeviceInfoChangeEvent"}, | ||
| 18 | {4, nullptr, "GetUpdateProgressInfo"}, | ||
| 19 | {5, nullptr, "GetLastInternalResult"}, | ||
| 20 | |||
| 21 | }; | ||
| 22 | // clang-format on | ||
| 23 | |||
| 24 | RegisterHandlers(functions); | ||
| 25 | } | ||
| 26 | |||
| 27 | ICradleFirmwareUpdater::~ICradleFirmwareUpdater() = default; | ||
| 28 | |||
| 29 | Result ICradleFirmwareUpdater::StartUpdate() { | ||
| 30 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 31 | R_SUCCEED(); | ||
| 32 | } | ||
| 33 | |||
| 34 | Result ICradleFirmwareUpdater::FinishUpdate() { | ||
| 35 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 36 | R_SUCCEED(); | ||
| 37 | } | ||
| 38 | |||
| 39 | Result ICradleFirmwareUpdater::GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info) { | ||
| 40 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 41 | *out_cradle_device_info = {}; | ||
| 42 | R_SUCCEED(); | ||
| 43 | } | ||
| 44 | |||
| 45 | Result ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent( | ||
| 46 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 47 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 48 | *out_event = m_cradle_device_info_event.GetHandle(); | ||
| 49 | R_SUCCEED(); | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.h b/src/core/hle/service/am/service/cradle_firmware_updater.h new file mode 100644 index 000000000..3e803f0ae --- /dev/null +++ b/src/core/hle/service/am/service/cradle_firmware_updater.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/os/event.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | struct CradleDeviceInfo { | ||
| 14 | bool unknown0; | ||
| 15 | bool unknown1; | ||
| 16 | bool unknown2; | ||
| 17 | u64 unknown3; | ||
| 18 | }; | ||
| 19 | static_assert(sizeof(CradleDeviceInfo) == 0x10, "CradleDeviceInfo has incorrect size"); | ||
| 20 | |||
| 21 | class ICradleFirmwareUpdater final : public ServiceFramework<ICradleFirmwareUpdater> { | ||
| 22 | public: | ||
| 23 | explicit ICradleFirmwareUpdater(Core::System& system_); | ||
| 24 | ~ICradleFirmwareUpdater() override; | ||
| 25 | |||
| 26 | private: | ||
| 27 | Result StartUpdate(); | ||
| 28 | Result FinishUpdate(); | ||
| 29 | Result GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info); | ||
| 30 | Result GetCradleDeviceInfoChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 31 | |||
| 32 | private: | ||
| 33 | KernelHelpers::ServiceContext m_context; | ||
| 34 | Event m_cradle_device_info_event; | ||
| 35 | }; | ||
| 36 | |||
| 37 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/debug_functions.cpp b/src/core/hle/service/am/service/debug_functions.cpp index f80b970f2..fcac4776d 100644 --- a/src/core/hle/service/am/debug_functions.cpp +++ b/src/core/hle/service/am/service/debug_functions.cpp | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/debug_functions.h" | 4 | #include "core/hle/service/am/service/debug_functions.h" |
| 5 | #include "core/hle/service/ipc_helpers.h" | ||
| 6 | 5 | ||
| 7 | namespace Service::AM { | 6 | namespace Service::AM { |
| 8 | 7 | ||
diff --git a/src/core/hle/service/am/debug_functions.h b/src/core/hle/service/am/service/debug_functions.h index d55968743..d55968743 100644 --- a/src/core/hle/service/am/debug_functions.h +++ b/src/core/hle/service/am/service/debug_functions.h | |||
diff --git a/src/core/hle/service/am/service/display_controller.cpp b/src/core/hle/service/am/service/display_controller.cpp new file mode 100644 index 000000000..249c73dfb --- /dev/null +++ b/src/core/hle/service/am/service/display_controller.cpp | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/result.h" | ||
| 5 | #include "core/hle/service/am/applet.h" | ||
| 6 | #include "core/hle/service/am/service/display_controller.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 12 | : ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, nullptr, "GetLastForegroundCaptureImage"}, | ||
| 16 | {1, nullptr, "UpdateLastForegroundCaptureImage"}, | ||
| 17 | {2, nullptr, "GetLastApplicationCaptureImage"}, | ||
| 18 | {3, nullptr, "GetCallerAppletCaptureImage"}, | ||
| 19 | {4, nullptr, "UpdateCallerAppletCaptureImage"}, | ||
| 20 | {5, nullptr, "GetLastForegroundCaptureImageEx"}, | ||
| 21 | {6, nullptr, "GetLastApplicationCaptureImageEx"}, | ||
| 22 | {7, D<&IDisplayController::GetCallerAppletCaptureImageEx>, "GetCallerAppletCaptureImageEx"}, | ||
| 23 | {8, D<&IDisplayController::TakeScreenShotOfOwnLayer>, "TakeScreenShotOfOwnLayer"}, | ||
| 24 | {9, nullptr, "CopyBetweenCaptureBuffers"}, | ||
| 25 | {10, nullptr, "AcquireLastApplicationCaptureBuffer"}, | ||
| 26 | {11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, | ||
| 27 | {12, nullptr, "AcquireLastForegroundCaptureBuffer"}, | ||
| 28 | {13, nullptr, "ReleaseLastForegroundCaptureBuffer"}, | ||
| 29 | {14, nullptr, "AcquireCallerAppletCaptureBuffer"}, | ||
| 30 | {15, nullptr, "ReleaseCallerAppletCaptureBuffer"}, | ||
| 31 | {16, nullptr, "AcquireLastApplicationCaptureBufferEx"}, | ||
| 32 | {17, nullptr, "AcquireLastForegroundCaptureBufferEx"}, | ||
| 33 | {18, nullptr, "AcquireCallerAppletCaptureBufferEx"}, | ||
| 34 | {20, D<&IDisplayController::ClearCaptureBuffer>, "ClearCaptureBuffer"}, | ||
| 35 | {21, nullptr, "ClearAppletTransitionBuffer"}, | ||
| 36 | {22, D<&IDisplayController::AcquireLastApplicationCaptureSharedBuffer>, "AcquireLastApplicationCaptureSharedBuffer"}, | ||
| 37 | {23, D<&IDisplayController::ReleaseLastApplicationCaptureSharedBuffer>, "ReleaseLastApplicationCaptureSharedBuffer"}, | ||
| 38 | {24, D<&IDisplayController::AcquireLastForegroundCaptureSharedBuffer>, "AcquireLastForegroundCaptureSharedBuffer"}, | ||
| 39 | {25, D<&IDisplayController::ReleaseLastForegroundCaptureSharedBuffer>, "ReleaseLastForegroundCaptureSharedBuffer"}, | ||
| 40 | {26, D<&IDisplayController::AcquireCallerAppletCaptureSharedBuffer>, "AcquireCallerAppletCaptureSharedBuffer"}, | ||
| 41 | {27, D<&IDisplayController::ReleaseCallerAppletCaptureSharedBuffer>, "ReleaseCallerAppletCaptureSharedBuffer"}, | ||
| 42 | {28, nullptr, "TakeScreenShotOfOwnLayerEx"}, | ||
| 43 | }; | ||
| 44 | // clang-format on | ||
| 45 | |||
| 46 | RegisterHandlers(functions); | ||
| 47 | } | ||
| 48 | |||
| 49 | IDisplayController::~IDisplayController() = default; | ||
| 50 | |||
| 51 | Result IDisplayController::GetCallerAppletCaptureImageEx( | ||
| 52 | Out<bool> out_was_written, OutBuffer<BufferAttr_HipcMapAlias> out_image_data) { | ||
| 53 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 54 | *out_was_written = true; | ||
| 55 | R_SUCCEED(); | ||
| 56 | } | ||
| 57 | |||
| 58 | Result IDisplayController::TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index) { | ||
| 59 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 60 | R_SUCCEED(); | ||
| 61 | } | ||
| 62 | |||
| 63 | Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color) { | ||
| 64 | LOG_WARNING(Service_AM, "(STUBBED) called, unknown0={} fbshare_layer_index={} color={:#x}", | ||
| 65 | unknown0, fbshare_layer_index, color); | ||
| 66 | R_SUCCEED(); | ||
| 67 | } | ||
| 68 | |||
| 69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( | ||
| 70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
| 71 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 72 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
| 73 | out_fbshare_layer_index)); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() { | ||
| 77 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 78 | R_SUCCEED(); | ||
| 79 | } | ||
| 80 | |||
| 81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( | ||
| 82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
| 83 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 84 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
| 85 | out_fbshare_layer_index)); | ||
| 86 | } | ||
| 87 | |||
| 88 | Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() { | ||
| 89 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 90 | R_SUCCEED(); | ||
| 91 | } | ||
| 92 | |||
| 93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( | ||
| 94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
| 95 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 96 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
| 97 | out_fbshare_layer_index)); | ||
| 98 | } | ||
| 99 | |||
| 100 | Result IDisplayController::ReleaseLastApplicationCaptureSharedBuffer() { | ||
| 101 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 102 | R_SUCCEED(); | ||
| 103 | } | ||
| 104 | |||
| 105 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/display_controller.h b/src/core/hle/service/am/service/display_controller.h new file mode 100644 index 000000000..406fae21a --- /dev/null +++ b/src/core/hle/service/am/service/display_controller.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | |||
| 13 | class IDisplayController final : public ServiceFramework<IDisplayController> { | ||
| 14 | public: | ||
| 15 | explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 16 | ~IDisplayController() override; | ||
| 17 | |||
| 18 | private: | ||
| 19 | Result GetCallerAppletCaptureImageEx(Out<bool> out_was_written, | ||
| 20 | OutBuffer<BufferAttr_HipcMapAlias> out_image_data); | ||
| 21 | Result TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index); | ||
| 22 | Result ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color); | ||
| 23 | Result AcquireLastForegroundCaptureSharedBuffer(Out<bool> out_was_written, | ||
| 24 | Out<s32> out_fbshare_layer_index); | ||
| 25 | Result ReleaseLastForegroundCaptureSharedBuffer(); | ||
| 26 | Result AcquireCallerAppletCaptureSharedBuffer(Out<bool> out_was_written, | ||
| 27 | Out<s32> out_fbshare_layer_index); | ||
| 28 | Result ReleaseCallerAppletCaptureSharedBuffer(); | ||
| 29 | Result AcquireLastApplicationCaptureSharedBuffer(Out<bool> out_was_written, | ||
| 30 | Out<s32> out_fbshare_layer_index); | ||
| 31 | Result ReleaseLastApplicationCaptureSharedBuffer(); | ||
| 32 | |||
| 33 | const std::shared_ptr<Applet> applet; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/global_state_controller.cpp b/src/core/hle/service/am/service/global_state_controller.cpp new file mode 100644 index 000000000..dba5d3613 --- /dev/null +++ b/src/core/hle/service/am/service/global_state_controller.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/cradle_firmware_updater.h" | ||
| 5 | #include "core/hle/service/am/service/global_state_controller.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | IGlobalStateController::IGlobalStateController(Core::System& system_) | ||
| 11 | : ServiceFramework{system_, "IGlobalStateController"}, | ||
| 12 | m_context{system_, "IGlobalStateController"}, m_hdcp_authentication_failed_event{m_context} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, nullptr, "RequestToEnterSleep"}, | ||
| 16 | {1, nullptr, "EnterSleep"}, | ||
| 17 | {2, nullptr, "StartSleepSequence"}, | ||
| 18 | {3, nullptr, "StartShutdownSequence"}, | ||
| 19 | {4, nullptr, "StartRebootSequence"}, | ||
| 20 | {9, nullptr, "IsAutoPowerDownRequested"}, | ||
| 21 | {10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"}, | ||
| 22 | {11, nullptr, "NotifyCecSettingsChanged"}, | ||
| 23 | {12, nullptr, "SetDefaultHomeButtonLongPressTime"}, | ||
| 24 | {13, nullptr, "UpdateDefaultDisplayResolution"}, | ||
| 25 | {14, D<&IGlobalStateController::ShouldSleepOnBoot>, "ShouldSleepOnBoot"}, | ||
| 26 | {15, D<&IGlobalStateController::GetHdcpAuthenticationFailedEvent>, "GetHdcpAuthenticationFailedEvent"}, | ||
| 27 | {30, D<&IGlobalStateController::OpenCradleFirmwareUpdater>, "OpenCradleFirmwareUpdater"}, | ||
| 28 | }; | ||
| 29 | // clang-format on | ||
| 30 | |||
| 31 | RegisterHandlers(functions); | ||
| 32 | } | ||
| 33 | |||
| 34 | IGlobalStateController::~IGlobalStateController() = default; | ||
| 35 | |||
| 36 | Result IGlobalStateController::LoadAndApplyIdlePolicySettings() { | ||
| 37 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 38 | R_SUCCEED(); | ||
| 39 | } | ||
| 40 | |||
| 41 | Result IGlobalStateController::ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot) { | ||
| 42 | LOG_INFO(Service_AM, "called"); | ||
| 43 | *out_should_sleep_on_boot = false; | ||
| 44 | R_SUCCEED(); | ||
| 45 | } | ||
| 46 | |||
| 47 | Result IGlobalStateController::GetHdcpAuthenticationFailedEvent( | ||
| 48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 49 | LOG_INFO(Service_AM, "called"); | ||
| 50 | *out_event = m_hdcp_authentication_failed_event.GetHandle(); | ||
| 51 | R_SUCCEED(); | ||
| 52 | } | ||
| 53 | |||
| 54 | Result IGlobalStateController::OpenCradleFirmwareUpdater( | ||
| 55 | Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater) { | ||
| 56 | LOG_INFO(Service_AM, "called"); | ||
| 57 | *out_cradle_firmware_updater = std::make_shared<ICradleFirmwareUpdater>(system); | ||
| 58 | R_SUCCEED(); | ||
| 59 | } | ||
| 60 | |||
| 61 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/global_state_controller.h b/src/core/hle/service/am/service/global_state_controller.h new file mode 100644 index 000000000..67c753513 --- /dev/null +++ b/src/core/hle/service/am/service/global_state_controller.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/os/event.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | class ICradleFirmwareUpdater; | ||
| 14 | |||
| 15 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | ||
| 16 | public: | ||
| 17 | explicit IGlobalStateController(Core::System& system_); | ||
| 18 | ~IGlobalStateController() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | Result LoadAndApplyIdlePolicySettings(); | ||
| 22 | Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot); | ||
| 23 | Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 24 | Result OpenCradleFirmwareUpdater( | ||
| 25 | Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater); | ||
| 26 | |||
| 27 | KernelHelpers::ServiceContext m_context; | ||
| 28 | Event m_hdcp_authentication_failed_event; | ||
| 29 | }; | ||
| 30 | |||
| 31 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.cpp b/src/core/hle/service/am/service/home_menu_functions.cpp new file mode 100644 index 000000000..0c4d24b58 --- /dev/null +++ b/src/core/hle/service/am/service/home_menu_functions.cpp | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/result.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet) | ||
| 12 | : ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)}, | ||
| 13 | m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, | ||
| 17 | {11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"}, | ||
| 18 | {12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"}, | ||
| 19 | {20, nullptr, "PopFromGeneralChannel"}, | ||
| 20 | {21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"}, | ||
| 21 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, | ||
| 22 | {31, nullptr, "GetWriterLockAccessorEx"}, | ||
| 23 | {40, nullptr, "IsSleepEnabled"}, | ||
| 24 | {41, D<&IHomeMenuFunctions::IsRebootEnabled>, "IsRebootEnabled"}, | ||
| 25 | {50, nullptr, "LaunchSystemApplet"}, | ||
| 26 | {51, nullptr, "LaunchStarter"}, | ||
| 27 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, | ||
| 28 | {110, D<&IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug>, "IsForceTerminateApplicationDisabledForDebug"}, | ||
| 29 | {200, nullptr, "LaunchDevMenu"}, | ||
| 30 | {1000, nullptr, "SetLastApplicationExitReason"}, | ||
| 31 | }; | ||
| 32 | // clang-format on | ||
| 33 | |||
| 34 | RegisterHandlers(functions); | ||
| 35 | } | ||
| 36 | |||
| 37 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; | ||
| 38 | |||
| 39 | Result IHomeMenuFunctions::RequestToGetForeground() { | ||
| 40 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 41 | R_SUCCEED(); | ||
| 42 | } | ||
| 43 | |||
| 44 | Result IHomeMenuFunctions::LockForeground() { | ||
| 45 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 46 | R_SUCCEED(); | ||
| 47 | } | ||
| 48 | |||
| 49 | Result IHomeMenuFunctions::UnlockForeground() { | ||
| 50 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 51 | R_SUCCEED(); | ||
| 52 | } | ||
| 53 | |||
| 54 | Result IHomeMenuFunctions::GetPopFromGeneralChannelEvent( | ||
| 55 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 56 | LOG_INFO(Service_AM, "called"); | ||
| 57 | *out_event = m_pop_from_general_channel_event.GetHandle(); | ||
| 58 | R_SUCCEED(); | ||
| 59 | } | ||
| 60 | |||
| 61 | Result IHomeMenuFunctions::IsRebootEnabled(Out<bool> out_is_reboot_enbaled) { | ||
| 62 | LOG_INFO(Service_AM, "called"); | ||
| 63 | *out_is_reboot_enbaled = true; | ||
| 64 | R_SUCCEED(); | ||
| 65 | } | ||
| 66 | |||
| 67 | Result IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug( | ||
| 68 | Out<bool> out_is_force_terminate_application_disabled_for_debug) { | ||
| 69 | LOG_INFO(Service_AM, "called"); | ||
| 70 | *out_is_force_terminate_application_disabled_for_debug = false; | ||
| 71 | R_SUCCEED(); | ||
| 72 | } | ||
| 73 | |||
| 74 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.h b/src/core/hle/service/am/service/home_menu_functions.h new file mode 100644 index 000000000..caf6fbaab --- /dev/null +++ b/src/core/hle/service/am/service/home_menu_functions.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/os/event.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | struct Applet; | ||
| 14 | |||
| 15 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | ||
| 16 | public: | ||
| 17 | explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 18 | ~IHomeMenuFunctions() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | Result RequestToGetForeground(); | ||
| 22 | Result LockForeground(); | ||
| 23 | Result UnlockForeground(); | ||
| 24 | Result GetPopFromGeneralChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 25 | Result IsRebootEnabled(Out<bool> out_is_reboot_enbaled); | ||
| 26 | Result IsForceTerminateApplicationDisabledForDebug( | ||
| 27 | Out<bool> out_is_force_terminate_application_disabled_for_debug); | ||
| 28 | |||
| 29 | const std::shared_ptr<Applet> m_applet; | ||
| 30 | KernelHelpers::ServiceContext m_context; | ||
| 31 | Event m_pop_from_general_channel_event; | ||
| 32 | }; | ||
| 33 | |||
| 34 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp new file mode 100644 index 000000000..0c2426d4b --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet_data_broker.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/frontend/applets.h" | ||
| 7 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
| 8 | #include "core/hle/service/am/service/storage.h" | ||
| 9 | #include "core/hle/service/cmif_serialization.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, | ||
| 14 | std::shared_ptr<AppletDataBroker> broker, | ||
| 15 | std::shared_ptr<Applet> applet) | ||
| 16 | : ServiceFramework{system_, "ILibraryAppletAccessor"}, m_broker{std::move(broker)}, | ||
| 17 | m_applet{std::move(applet)} { | ||
| 18 | // clang-format off | ||
| 19 | static const FunctionInfo functions[] = { | ||
| 20 | {0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, | ||
| 21 | {1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"}, | ||
| 22 | {10, D<&ILibraryAppletAccessor::Start>, "Start"}, | ||
| 23 | {20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"}, | ||
| 24 | {25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"}, | ||
| 25 | {30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"}, | ||
| 26 | {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, | ||
| 27 | {60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero"}, | ||
| 28 | {100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"}, | ||
| 29 | {101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"}, | ||
| 30 | {102, nullptr, "PushExtraStorage"}, | ||
| 31 | {103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"}, | ||
| 32 | {104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"}, | ||
| 33 | {105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"}, | ||
| 34 | {106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"}, | ||
| 35 | {110, nullptr, "NeedsToExitProcess"}, | ||
| 36 | {120, nullptr, "GetLibraryAppletInfo"}, | ||
| 37 | {150, nullptr, "RequestForAppletToGetForeground"}, | ||
| 38 | {160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, | ||
| 39 | }; | ||
| 40 | // clang-format on | ||
| 41 | |||
| 42 | RegisterHandlers(functions); | ||
| 43 | } | ||
| 44 | |||
| 45 | ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; | ||
| 46 | |||
| 47 | Result ILibraryAppletAccessor::GetAppletStateChangedEvent( | ||
| 48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 49 | LOG_DEBUG(Service_AM, "called"); | ||
| 50 | *out_event = m_broker->GetStateChangedEvent().GetHandle(); | ||
| 51 | R_SUCCEED(); | ||
| 52 | } | ||
| 53 | |||
| 54 | Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) { | ||
| 55 | LOG_DEBUG(Service_AM, "called"); | ||
| 56 | *out_is_completed = m_broker->IsCompleted(); | ||
| 57 | R_SUCCEED(); | ||
| 58 | } | ||
| 59 | |||
| 60 | Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) { | ||
| 61 | LOG_DEBUG(Service_AM, "called"); | ||
| 62 | *out_result = m_applet->terminate_result; | ||
| 63 | R_SUCCEED(); | ||
| 64 | } | ||
| 65 | |||
| 66 | Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() { | ||
| 67 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 68 | R_SUCCEED(); | ||
| 69 | } | ||
| 70 | |||
| 71 | Result ILibraryAppletAccessor::Start() { | ||
| 72 | LOG_DEBUG(Service_AM, "called"); | ||
| 73 | m_applet->process->Run(); | ||
| 74 | FrontendExecute(); | ||
| 75 | R_SUCCEED(); | ||
| 76 | } | ||
| 77 | |||
| 78 | Result ILibraryAppletAccessor::RequestExit() { | ||
| 79 | LOG_DEBUG(Service_AM, "called"); | ||
| 80 | m_applet->message_queue.RequestExit(); | ||
| 81 | FrontendRequestExit(); | ||
| 82 | R_SUCCEED(); | ||
| 83 | } | ||
| 84 | |||
| 85 | Result ILibraryAppletAccessor::Terminate() { | ||
| 86 | LOG_DEBUG(Service_AM, "called"); | ||
| 87 | m_applet->process->Terminate(); | ||
| 88 | FrontendRequestExit(); | ||
| 89 | R_SUCCEED(); | ||
| 90 | } | ||
| 91 | |||
| 92 | Result ILibraryAppletAccessor::PushInData(SharedPointer<IStorage> storage) { | ||
| 93 | LOG_DEBUG(Service_AM, "called"); | ||
| 94 | m_broker->GetInData().Push(storage); | ||
| 95 | R_SUCCEED(); | ||
| 96 | } | ||
| 97 | |||
| 98 | Result ILibraryAppletAccessor::PopOutData(Out<SharedPointer<IStorage>> out_storage) { | ||
| 99 | LOG_DEBUG(Service_AM, "called"); | ||
| 100 | R_RETURN(m_broker->GetOutData().Pop(out_storage.Get())); | ||
| 101 | } | ||
| 102 | |||
| 103 | Result ILibraryAppletAccessor::PushInteractiveInData(SharedPointer<IStorage> storage) { | ||
| 104 | LOG_DEBUG(Service_AM, "called"); | ||
| 105 | m_broker->GetInteractiveInData().Push(storage); | ||
| 106 | FrontendExecuteInteractive(); | ||
| 107 | R_SUCCEED(); | ||
| 108 | } | ||
| 109 | |||
| 110 | Result ILibraryAppletAccessor::PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage) { | ||
| 111 | LOG_DEBUG(Service_AM, "called"); | ||
| 112 | R_RETURN(m_broker->GetInteractiveOutData().Pop(out_storage.Get())); | ||
| 113 | } | ||
| 114 | |||
| 115 | Result ILibraryAppletAccessor::GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 116 | LOG_DEBUG(Service_AM, "called"); | ||
| 117 | *out_event = m_broker->GetOutData().GetEvent(); | ||
| 118 | R_SUCCEED(); | ||
| 119 | } | ||
| 120 | |||
| 121 | Result ILibraryAppletAccessor::GetPopInteractiveOutDataEvent( | ||
| 122 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 123 | LOG_DEBUG(Service_AM, "called"); | ||
| 124 | *out_event = m_broker->GetInteractiveOutData().GetEvent(); | ||
| 125 | R_SUCCEED(); | ||
| 126 | } | ||
| 127 | |||
| 128 | Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out<u64> out_handle) { | ||
| 129 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 130 | |||
| 131 | // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is | ||
| 132 | // actually used anywhere | ||
| 133 | *out_handle = 0xdeadbeef; | ||
| 134 | R_SUCCEED(); | ||
| 135 | } | ||
| 136 | |||
| 137 | void ILibraryAppletAccessor::FrontendExecute() { | ||
| 138 | if (m_applet->frontend) { | ||
| 139 | m_applet->frontend->Initialize(); | ||
| 140 | m_applet->frontend->Execute(); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | void ILibraryAppletAccessor::FrontendExecuteInteractive() { | ||
| 145 | if (m_applet->frontend) { | ||
| 146 | m_applet->frontend->ExecuteInteractive(); | ||
| 147 | m_applet->frontend->Execute(); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | void ILibraryAppletAccessor::FrontendRequestExit() { | ||
| 152 | if (m_applet->frontend) { | ||
| 153 | m_applet->frontend->RequestExit(); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_accessor.h b/src/core/hle/service/am/service/library_applet_accessor.h new file mode 100644 index 000000000..97d3b6c8a --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_accessor.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class AppletDataBroker; | ||
| 12 | struct Applet; | ||
| 13 | class IStorage; | ||
| 14 | |||
| 15 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | ||
| 16 | public: | ||
| 17 | explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<AppletDataBroker> broker, | ||
| 18 | std::shared_ptr<Applet> applet); | ||
| 19 | ~ILibraryAppletAccessor(); | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 23 | Result IsCompleted(Out<bool> out_is_completed); | ||
| 24 | Result GetResult(Out<Result> out_result); | ||
| 25 | Result PresetLibraryAppletGpuTimeSliceZero(); | ||
| 26 | Result Start(); | ||
| 27 | Result RequestExit(); | ||
| 28 | Result Terminate(); | ||
| 29 | Result PushInData(SharedPointer<IStorage> storage); | ||
| 30 | Result PopOutData(Out<SharedPointer<IStorage>> out_storage); | ||
| 31 | Result PushInteractiveInData(SharedPointer<IStorage> storage); | ||
| 32 | Result PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage); | ||
| 33 | Result GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 34 | Result GetPopInteractiveOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 35 | Result GetIndirectLayerConsumerHandle(Out<u64> out_handle); | ||
| 36 | |||
| 37 | void FrontendExecute(); | ||
| 38 | void FrontendExecuteInteractive(); | ||
| 39 | void FrontendRequestExit(); | ||
| 40 | |||
| 41 | const std::shared_ptr<AppletDataBroker> m_broker; | ||
| 42 | const std::shared_ptr<Applet> m_applet; | ||
| 43 | }; | ||
| 44 | |||
| 45 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 00d5a0705..166637d60 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp | |||
| @@ -6,11 +6,11 @@ | |||
| 6 | #include "core/hle/service/am/applet_data_broker.h" | 6 | #include "core/hle/service/am/applet_data_broker.h" |
| 7 | #include "core/hle/service/am/applet_manager.h" | 7 | #include "core/hle/service/am/applet_manager.h" |
| 8 | #include "core/hle/service/am/frontend/applets.h" | 8 | #include "core/hle/service/am/frontend/applets.h" |
| 9 | #include "core/hle/service/am/library_applet_accessor.h" | ||
| 10 | #include "core/hle/service/am/library_applet_creator.h" | ||
| 11 | #include "core/hle/service/am/library_applet_storage.h" | 9 | #include "core/hle/service/am/library_applet_storage.h" |
| 12 | #include "core/hle/service/am/storage.h" | 10 | #include "core/hle/service/am/service/library_applet_accessor.h" |
| 13 | #include "core/hle/service/ipc_helpers.h" | 11 | #include "core/hle/service/am/service/library_applet_creator.h" |
| 12 | #include "core/hle/service/am/service/storage.h" | ||
| 13 | #include "core/hle/service/cmif_serialization.h" | ||
| 14 | #include "core/hle/service/sm/sm.h" | 14 | #include "core/hle/service/sm/sm.h" |
| 15 | 15 | ||
| 16 | namespace Service::AM { | 16 | namespace Service::AM { |
| @@ -130,13 +130,13 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | |||
| 130 | case LibraryAppletMode::PartialForegroundIndirectDisplay: | 130 | case LibraryAppletMode::PartialForegroundIndirectDisplay: |
| 131 | applet->hid_registration.EnableAppletToGetInput(true); | 131 | applet->hid_registration.EnableAppletToGetInput(true); |
| 132 | applet->focus_state = FocusState::InFocus; | 132 | applet->focus_state = FocusState::InFocus; |
| 133 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | 133 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); |
| 134 | break; | 134 | break; |
| 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: | 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: |
| 136 | applet->hid_registration.EnableAppletToGetInput(false); | 136 | applet->hid_registration.EnableAppletToGetInput(false); |
| 137 | applet->focus_state = FocusState::NotInFocus; | 137 | applet->focus_state = FocusState::NotInFocus; |
| 138 | applet->system_buffer_manager.SetWindowVisibility(false); | 138 | applet->system_buffer_manager.SetWindowVisibility(false); |
| 139 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground); | 139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); |
| 140 | break; | 140 | break; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| @@ -172,139 +172,97 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste | |||
| 172 | 172 | ||
| 173 | } // namespace | 173 | } // namespace |
| 174 | 174 | ||
| 175 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_) | 175 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet) |
| 176 | : ServiceFramework{system_, "ILibraryAppletCreator"}, applet{std::move(applet_)} { | 176 | : ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} { |
| 177 | static const FunctionInfo functions[] = { | 177 | static const FunctionInfo functions[] = { |
| 178 | {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"}, | 178 | {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, |
| 179 | {1, nullptr, "TerminateAllLibraryApplets"}, | 179 | {1, nullptr, "TerminateAllLibraryApplets"}, |
| 180 | {2, nullptr, "AreAnyLibraryAppletsLeft"}, | 180 | {2, nullptr, "AreAnyLibraryAppletsLeft"}, |
| 181 | {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"}, | 181 | {10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"}, |
| 182 | {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"}, | 182 | {11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"}, |
| 183 | {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"}, | 183 | {12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"}, |
| 184 | }; | 184 | }; |
| 185 | RegisterHandlers(functions); | 185 | RegisterHandlers(functions); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; | 188 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; |
| 189 | 189 | ||
| 190 | void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { | 190 | Result ILibraryAppletCreator::CreateLibraryApplet( |
| 191 | IPC::RequestParser rp{ctx}; | 191 | Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id, |
| 192 | 192 | LibraryAppletMode library_applet_mode) { | |
| 193 | const auto applet_id = rp.PopRaw<AppletId>(); | 193 | LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={}", applet_id, |
| 194 | const auto applet_mode = rp.PopRaw<LibraryAppletMode>(); | 194 | library_applet_mode); |
| 195 | |||
| 196 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, | ||
| 197 | applet_mode); | ||
| 198 | 195 | ||
| 199 | std::shared_ptr<ILibraryAppletAccessor> library_applet; | 196 | std::shared_ptr<ILibraryAppletAccessor> library_applet; |
| 200 | if (ShouldCreateGuestApplet(applet_id)) { | 197 | if (ShouldCreateGuestApplet(applet_id)) { |
| 201 | library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); | 198 | library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode); |
| 202 | } | 199 | } |
| 203 | if (!library_applet) { | 200 | if (!library_applet) { |
| 204 | library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); | 201 | library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode); |
| 205 | } | 202 | } |
| 206 | if (!library_applet) { | 203 | if (!library_applet) { |
| 207 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); | 204 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); |
| 208 | 205 | R_THROW(ResultUnknown); | |
| 209 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 210 | rb.Push(ResultUnknown); | ||
| 211 | return; | ||
| 212 | } | 206 | } |
| 213 | 207 | ||
| 214 | // Applet is created, can now be launched. | 208 | // Applet is created, can now be launched. |
| 215 | applet->library_applet_launchable_event.Signal(); | 209 | m_applet->library_applet_launchable_event.Signal(); |
| 216 | 210 | *out_library_applet_accessor = library_applet; | |
| 217 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 211 | R_SUCCEED(); |
| 218 | rb.Push(ResultSuccess); | ||
| 219 | rb.PushIpcInterface<ILibraryAppletAccessor>(library_applet); | ||
| 220 | } | 212 | } |
| 221 | 213 | ||
| 222 | void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) { | 214 | Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) { |
| 223 | IPC::RequestParser rp{ctx}; | ||
| 224 | |||
| 225 | const s64 size{rp.Pop<s64>()}; | ||
| 226 | |||
| 227 | LOG_DEBUG(Service_AM, "called, size={}", size); | 215 | LOG_DEBUG(Service_AM, "called, size={}", size); |
| 228 | 216 | ||
| 229 | if (size <= 0) { | 217 | if (size <= 0) { |
| 230 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | 218 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); |
| 231 | IPC::ResponseBuilder rb{ctx, 2}; | 219 | R_THROW(ResultUnknown); |
| 232 | rb.Push(ResultUnknown); | ||
| 233 | return; | ||
| 234 | } | 220 | } |
| 235 | 221 | ||
| 236 | std::vector<u8> data(size); | 222 | *out_storage = std::make_shared<IStorage>(system, AM::CreateStorage(std::vector<u8>(size))); |
| 237 | 223 | R_SUCCEED(); | |
| 238 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 239 | rb.Push(ResultSuccess); | ||
| 240 | rb.PushIpcInterface<IStorage>(system, AM::CreateStorage(std::move(data))); | ||
| 241 | } | 224 | } |
| 242 | 225 | ||
| 243 | void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) { | 226 | Result ILibraryAppletCreator::CreateTransferMemoryStorage( |
| 244 | IPC::RequestParser rp{ctx}; | 227 | Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size, |
| 245 | 228 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | |
| 246 | struct Parameters { | 229 | LOG_DEBUG(Service_AM, "called, is_writable={} size={}", is_writable, size); |
| 247 | bool is_writable; | ||
| 248 | s64 size; | ||
| 249 | }; | ||
| 250 | 230 | ||
| 251 | const auto params{rp.PopRaw<Parameters>()}; | 231 | if (size <= 0) { |
| 252 | const auto handle{ctx.GetCopyHandle(0)}; | ||
| 253 | |||
| 254 | LOG_DEBUG(Service_AM, "called, is_writable={}, size={}, handle={:08X}", params.is_writable, | ||
| 255 | params.size, handle); | ||
| 256 | |||
| 257 | if (params.size <= 0) { | ||
| 258 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | 232 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); |
| 259 | IPC::ResponseBuilder rb{ctx, 2}; | 233 | R_THROW(ResultUnknown); |
| 260 | rb.Push(ResultUnknown); | ||
| 261 | return; | ||
| 262 | } | 234 | } |
| 263 | 235 | ||
| 264 | auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle); | 236 | if (!transfer_memory_handle) { |
| 265 | 237 | LOG_ERROR(Service_AM, "transfer_memory_handle is null"); | |
| 266 | if (transfer_mem.IsNull()) { | 238 | R_THROW(ResultUnknown); |
| 267 | LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); | ||
| 268 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 269 | rb.Push(ResultUnknown); | ||
| 270 | return; | ||
| 271 | } | 239 | } |
| 272 | 240 | ||
| 273 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 241 | *out_storage = std::make_shared<IStorage>( |
| 274 | rb.Push(ResultSuccess); | 242 | system, AM::CreateTransferMemoryStorage(transfer_memory_handle->GetOwner()->GetMemory(), |
| 275 | rb.PushIpcInterface<IStorage>( | 243 | transfer_memory_handle.Get(), is_writable, size)); |
| 276 | system, AM::CreateTransferMemoryStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(), | 244 | R_SUCCEED(); |
| 277 | params.is_writable, params.size)); | ||
| 278 | } | 245 | } |
| 279 | 246 | ||
| 280 | void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { | 247 | Result ILibraryAppletCreator::CreateHandleStorage( |
| 281 | IPC::RequestParser rp{ctx}; | 248 | Out<SharedPointer<IStorage>> out_storage, s64 size, |
| 282 | 249 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | |
| 283 | const s64 size{rp.Pop<s64>()}; | 250 | LOG_DEBUG(Service_AM, "called, size={}", size); |
| 284 | const auto handle{ctx.GetCopyHandle(0)}; | ||
| 285 | |||
| 286 | LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle); | ||
| 287 | 251 | ||
| 288 | if (size <= 0) { | 252 | if (size <= 0) { |
| 289 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | 253 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); |
| 290 | IPC::ResponseBuilder rb{ctx, 2}; | 254 | R_THROW(ResultUnknown); |
| 291 | rb.Push(ResultUnknown); | ||
| 292 | return; | ||
| 293 | } | 255 | } |
| 294 | 256 | ||
| 295 | auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle); | 257 | if (!transfer_memory_handle) { |
| 296 | 258 | LOG_ERROR(Service_AM, "transfer_memory_handle is null"); | |
| 297 | if (transfer_mem.IsNull()) { | 259 | R_THROW(ResultUnknown); |
| 298 | LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); | ||
| 299 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 300 | rb.Push(ResultUnknown); | ||
| 301 | return; | ||
| 302 | } | 260 | } |
| 303 | 261 | ||
| 304 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 262 | *out_storage = std::make_shared<IStorage>( |
| 305 | rb.Push(ResultSuccess); | 263 | system, AM::CreateHandleStorage(transfer_memory_handle->GetOwner()->GetMemory(), |
| 306 | rb.PushIpcInterface<IStorage>( | 264 | transfer_memory_handle.Get(), size)); |
| 307 | system, AM::CreateHandleStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(), size)); | 265 | R_SUCCEED(); |
| 308 | } | 266 | } |
| 309 | 267 | ||
| 310 | } // namespace Service::AM | 268 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/library_applet_creator.h b/src/core/hle/service/am/service/library_applet_creator.h new file mode 100644 index 000000000..fe6d40eb3 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_creator.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/am/am_types.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | struct Applet; | ||
| 13 | class ILibraryAppletAccessor; | ||
| 14 | class IStorage; | ||
| 15 | |||
| 16 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | ||
| 17 | public: | ||
| 18 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 19 | ~ILibraryAppletCreator() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result CreateLibraryApplet( | ||
| 23 | Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id, | ||
| 24 | LibraryAppletMode library_applet_mode); | ||
| 25 | Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size); | ||
| 26 | Result CreateTransferMemoryStorage( | ||
| 27 | Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size, | ||
| 28 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
| 29 | Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size, | ||
| 30 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
| 31 | |||
| 32 | const std::shared_ptr<Applet> m_applet; | ||
| 33 | }; | ||
| 34 | |||
| 35 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp new file mode 100644 index 000000000..bcb44a71c --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/service/audio_controller.h" | ||
| 6 | #include "core/hle/service/am/service/common_state_getter.h" | ||
| 7 | #include "core/hle/service/am/service/debug_functions.h" | ||
| 8 | #include "core/hle/service/am/service/display_controller.h" | ||
| 9 | #include "core/hle/service/am/service/global_state_controller.h" | ||
| 10 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
| 11 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
| 12 | #include "core/hle/service/am/service/library_applet_proxy.h" | ||
| 13 | #include "core/hle/service/am/service/library_applet_self_accessor.h" | ||
| 14 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
| 15 | #include "core/hle/service/am/service/self_controller.h" | ||
| 16 | #include "core/hle/service/am/service/window_controller.h" | ||
| 17 | #include "core/hle/service/cmif_serialization.h" | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 22 | Kernel::KProcess* process, | ||
| 23 | Nvnflinger::Nvnflinger& nvnflinger) | ||
| 24 | : ServiceFramework{system_, "ILibraryAppletProxy"}, | ||
| 25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 26 | // clang-format off | ||
| 27 | static const FunctionInfo functions[] = { | ||
| 28 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
| 29 | {1, D<&ILibraryAppletProxy::GetSelfController>, "GetSelfController"}, | ||
| 30 | {2, D<&ILibraryAppletProxy::GetWindowController>, "GetWindowController"}, | ||
| 31 | {3, D<&ILibraryAppletProxy::GetAudioController>, "GetAudioController"}, | ||
| 32 | {4, D<&ILibraryAppletProxy::GetDisplayController>, "GetDisplayController"}, | ||
| 33 | {10, D<&ILibraryAppletProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
| 34 | {11, D<&ILibraryAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
| 35 | {20, D<&ILibraryAppletProxy::OpenLibraryAppletSelfAccessor>, "OpenLibraryAppletSelfAccessor"}, | ||
| 36 | {21, D<&ILibraryAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"}, | ||
| 37 | {22, D<&ILibraryAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"}, | ||
| 38 | {23, D<&ILibraryAppletProxy::GetGlobalStateController>, "GetGlobalStateController"}, | ||
| 39 | {1000, D<&ILibraryAppletProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | |||
| 46 | ILibraryAppletProxy::~ILibraryAppletProxy() = default; | ||
| 47 | |||
| 48 | Result ILibraryAppletProxy::GetAudioController( | ||
| 49 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
| 50 | LOG_DEBUG(Service_AM, "called"); | ||
| 51 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
| 52 | R_SUCCEED(); | ||
| 53 | } | ||
| 54 | |||
| 55 | Result ILibraryAppletProxy::GetDisplayController( | ||
| 56 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
| 57 | LOG_DEBUG(Service_AM, "called"); | ||
| 58 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | Result ILibraryAppletProxy::GetProcessWindingController( | ||
| 63 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
| 64 | LOG_DEBUG(Service_AM, "called"); | ||
| 65 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
| 66 | R_SUCCEED(); | ||
| 67 | } | ||
| 68 | |||
| 69 | Result ILibraryAppletProxy::GetDebugFunctions( | ||
| 70 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
| 71 | LOG_DEBUG(Service_AM, "called"); | ||
| 72 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
| 73 | R_SUCCEED(); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result ILibraryAppletProxy::GetWindowController( | ||
| 77 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
| 78 | LOG_DEBUG(Service_AM, "called"); | ||
| 79 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
| 80 | R_SUCCEED(); | ||
| 81 | } | ||
| 82 | |||
| 83 | Result ILibraryAppletProxy::GetSelfController( | ||
| 84 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
| 85 | LOG_DEBUG(Service_AM, "called"); | ||
| 86 | *out_self_controller = | ||
| 87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 88 | R_SUCCEED(); | ||
| 89 | } | ||
| 90 | |||
| 91 | Result ILibraryAppletProxy::GetCommonStateGetter( | ||
| 92 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
| 93 | LOG_DEBUG(Service_AM, "called"); | ||
| 94 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
| 95 | R_SUCCEED(); | ||
| 96 | } | ||
| 97 | |||
| 98 | Result ILibraryAppletProxy::GetLibraryAppletCreator( | ||
| 99 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
| 100 | LOG_DEBUG(Service_AM, "called"); | ||
| 101 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
| 102 | R_SUCCEED(); | ||
| 103 | } | ||
| 104 | |||
| 105 | Result ILibraryAppletProxy::OpenLibraryAppletSelfAccessor( | ||
| 106 | Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor) { | ||
| 107 | LOG_DEBUG(Service_AM, "called"); | ||
| 108 | *out_library_applet_self_accessor = | ||
| 109 | std::make_shared<ILibraryAppletSelfAccessor>(system, m_applet); | ||
| 110 | R_SUCCEED(); | ||
| 111 | } | ||
| 112 | |||
| 113 | Result ILibraryAppletProxy::GetAppletCommonFunctions( | ||
| 114 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) { | ||
| 115 | LOG_DEBUG(Service_AM, "called"); | ||
| 116 | *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet); | ||
| 117 | R_SUCCEED(); | ||
| 118 | } | ||
| 119 | |||
| 120 | Result ILibraryAppletProxy::GetHomeMenuFunctions( | ||
| 121 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | ||
| 122 | LOG_DEBUG(Service_AM, "called"); | ||
| 123 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | ||
| 124 | R_SUCCEED(); | ||
| 125 | } | ||
| 126 | |||
| 127 | Result ILibraryAppletProxy::GetGlobalStateController( | ||
| 128 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller) { | ||
| 129 | LOG_DEBUG(Service_AM, "called"); | ||
| 130 | *out_global_state_controller = std::make_shared<IGlobalStateController>(system); | ||
| 131 | R_SUCCEED(); | ||
| 132 | } | ||
| 133 | |||
| 134 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h new file mode 100644 index 000000000..23e64e295 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_proxy.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | class IAppletCommonFunctions; | ||
| 13 | class IAudioController; | ||
| 14 | class ICommonStateGetter; | ||
| 15 | class IDebugFunctions; | ||
| 16 | class IDisplayController; | ||
| 17 | class IHomeMenuFunctions; | ||
| 18 | class IGlobalStateController; | ||
| 19 | class ILibraryAppletCreator; | ||
| 20 | class ILibraryAppletSelfAccessor; | ||
| 21 | class IProcessWindingController; | ||
| 22 | class ISelfController; | ||
| 23 | class IWindowController; | ||
| 24 | |||
| 25 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | ||
| 26 | public: | ||
| 27 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
| 29 | ~ILibraryAppletProxy(); | ||
| 30 | |||
| 31 | private: | ||
| 32 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
| 33 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
| 34 | Result GetProcessWindingController( | ||
| 35 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
| 36 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
| 37 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
| 38 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
| 39 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
| 40 | Result GetLibraryAppletCreator( | ||
| 41 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
| 42 | Result OpenLibraryAppletSelfAccessor( | ||
| 43 | Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor); | ||
| 44 | Result GetAppletCommonFunctions( | ||
| 45 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions); | ||
| 46 | Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions); | ||
| 47 | Result GetGlobalStateController( | ||
| 48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | ||
| 49 | |||
| 50 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 51 | Kernel::KProcess* const m_process; | ||
| 52 | const std::shared_ptr<Applet> m_applet; | ||
| 53 | }; | ||
| 54 | |||
| 55 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp new file mode 100644 index 000000000..7a3a86e88 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp | |||
| @@ -0,0 +1,322 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core_timing.h" | ||
| 5 | #include "core/file_sys/control_metadata.h" | ||
| 6 | #include "core/file_sys/patch_manager.h" | ||
| 7 | #include "core/file_sys/registered_cache.h" | ||
| 8 | #include "core/hle/service/acc/profile_manager.h" | ||
| 9 | #include "core/hle/service/am/applet_data_broker.h" | ||
| 10 | #include "core/hle/service/am/applet_manager.h" | ||
| 11 | #include "core/hle/service/am/frontend/applets.h" | ||
| 12 | #include "core/hle/service/am/service/library_applet_self_accessor.h" | ||
| 13 | #include "core/hle/service/am/service/storage.h" | ||
| 14 | #include "core/hle/service/cmif_serialization.h" | ||
| 15 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 16 | #include "core/hle/service/glue/glue_manager.h" | ||
| 17 | #include "core/hle/service/ns/ns.h" | ||
| 18 | #include "core/hle/service/sm/sm.h" | ||
| 19 | |||
| 20 | namespace Service::AM { | ||
| 21 | |||
| 22 | namespace { | ||
| 23 | |||
| 24 | AppletIdentityInfo GetCallerIdentity(Applet& applet) { | ||
| 25 | if (const auto caller_applet = applet.caller_applet.lock(); caller_applet) { | ||
| 26 | // TODO: is this actually the application ID? | ||
| 27 | return { | ||
| 28 | .applet_id = caller_applet->applet_id, | ||
| 29 | .application_id = caller_applet->program_id, | ||
| 30 | }; | ||
| 31 | } else { | ||
| 32 | return { | ||
| 33 | .applet_id = AppletId::QLaunch, | ||
| 34 | .application_id = 0x0100000000001000ull, | ||
| 35 | }; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | } // namespace | ||
| 40 | |||
| 41 | ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_, | ||
| 42 | std::shared_ptr<Applet> applet) | ||
| 43 | : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)}, | ||
| 44 | m_broker{m_applet->caller_applet_broker} { | ||
| 45 | // clang-format off | ||
| 46 | static const FunctionInfo functions[] = { | ||
| 47 | {0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"}, | ||
| 48 | {1, D<&ILibraryAppletSelfAccessor::PushOutData>, "PushOutData"}, | ||
| 49 | {2, D<&ILibraryAppletSelfAccessor::PopInteractiveInData>, "PopInteractiveInData"}, | ||
| 50 | {3, D<&ILibraryAppletSelfAccessor::PushInteractiveOutData>, "PushInteractiveOutData"}, | ||
| 51 | {5, D<&ILibraryAppletSelfAccessor::GetPopInDataEvent>, "GetPopInDataEvent"}, | ||
| 52 | {6, D<&ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent>, "GetPopInteractiveInDataEvent"}, | ||
| 53 | {10, D<&ILibraryAppletSelfAccessor::ExitProcessAndReturn>, "ExitProcessAndReturn"}, | ||
| 54 | {11, D<&ILibraryAppletSelfAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"}, | ||
| 55 | {12, D<&ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo>, "GetMainAppletIdentityInfo"}, | ||
| 56 | {13, D<&ILibraryAppletSelfAccessor::CanUseApplicationCore>, "CanUseApplicationCore"}, | ||
| 57 | {14, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo>, "GetCallerAppletIdentityInfo"}, | ||
| 58 | {15, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty>, "GetMainAppletApplicationControlProperty"}, | ||
| 59 | {16, D<&ILibraryAppletSelfAccessor::GetMainAppletStorageId>, "GetMainAppletStorageId"}, | ||
| 60 | {17, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack>, "GetCallerAppletIdentityInfoStack"}, | ||
| 61 | {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"}, | ||
| 62 | {19, D<&ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout>, "GetDesirableKeyboardLayout"}, | ||
| 63 | {20, nullptr, "PopExtraStorage"}, | ||
| 64 | {25, nullptr, "GetPopExtraStorageEvent"}, | ||
| 65 | {30, nullptr, "UnpopInData"}, | ||
| 66 | {31, nullptr, "UnpopExtraStorage"}, | ||
| 67 | {40, nullptr, "GetIndirectLayerProducerHandle"}, | ||
| 68 | {50, D<&ILibraryAppletSelfAccessor::ReportVisibleError>, "ReportVisibleError"}, | ||
| 69 | {51, D<&ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext>, "ReportVisibleErrorWithErrorContext"}, | ||
| 70 | {60, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage>, "GetMainAppletApplicationDesiredLanguage"}, | ||
| 71 | {70, D<&ILibraryAppletSelfAccessor::GetCurrentApplicationId>, "GetCurrentApplicationId"}, | ||
| 72 | {80, nullptr, "RequestExitToSelf"}, | ||
| 73 | {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"}, | ||
| 74 | {100, nullptr, "CreateGameMovieTrimmer"}, | ||
| 75 | {101, nullptr, "ReserveResourceForMovieOperation"}, | ||
| 76 | {102, nullptr, "UnreserveResourceForMovieOperation"}, | ||
| 77 | {110, D<&ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers>, "GetMainAppletAvailableUsers"}, | ||
| 78 | {120, nullptr, "GetLaunchStorageInfoForDebug"}, | ||
| 79 | {130, nullptr, "GetGpuErrorDetectedSystemEvent"}, | ||
| 80 | {140, nullptr, "SetApplicationMemoryReservation"}, | ||
| 81 | {150, D<&ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually>, "ShouldSetGpuTimeSliceManually"}, | ||
| 82 | {160, D<&ILibraryAppletSelfAccessor::Cmd160>, "Cmd160"}, | ||
| 83 | }; | ||
| 84 | // clang-format on | ||
| 85 | RegisterHandlers(functions); | ||
| 86 | } | ||
| 87 | |||
| 88 | ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; | ||
| 89 | |||
| 90 | Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_storage) { | ||
| 91 | LOG_INFO(Service_AM, "called"); | ||
| 92 | R_RETURN(m_broker->GetInData().Pop(out_storage)); | ||
| 93 | } | ||
| 94 | |||
| 95 | Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) { | ||
| 96 | LOG_INFO(Service_AM, "called"); | ||
| 97 | m_broker->GetOutData().Push(storage); | ||
| 98 | R_SUCCEED(); | ||
| 99 | } | ||
| 100 | |||
| 101 | Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage) { | ||
| 102 | LOG_INFO(Service_AM, "called"); | ||
| 103 | R_RETURN(m_broker->GetInteractiveInData().Pop(out_storage)); | ||
| 104 | } | ||
| 105 | |||
| 106 | Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer<IStorage> storage) { | ||
| 107 | LOG_INFO(Service_AM, "called"); | ||
| 108 | m_broker->GetInteractiveOutData().Push(storage); | ||
| 109 | R_SUCCEED(); | ||
| 110 | } | ||
| 111 | |||
| 112 | Result ILibraryAppletSelfAccessor::GetPopInDataEvent( | ||
| 113 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 114 | LOG_INFO(Service_AM, "called"); | ||
| 115 | *out_event = m_broker->GetInData().GetEvent(); | ||
| 116 | R_SUCCEED(); | ||
| 117 | } | ||
| 118 | |||
| 119 | Result ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent( | ||
| 120 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 121 | LOG_INFO(Service_AM, "called"); | ||
| 122 | *out_event = m_broker->GetInteractiveInData().GetEvent(); | ||
| 123 | R_SUCCEED(); | ||
| 124 | } | ||
| 125 | |||
| 126 | Result ILibraryAppletSelfAccessor::GetLibraryAppletInfo( | ||
| 127 | Out<LibraryAppletInfo> out_library_applet_info) { | ||
| 128 | LOG_INFO(Service_AM, "called"); | ||
| 129 | *out_library_applet_info = { | ||
| 130 | .applet_id = m_applet->applet_id, | ||
| 131 | .library_applet_mode = m_applet->library_applet_mode, | ||
| 132 | }; | ||
| 133 | R_SUCCEED(); | ||
| 134 | } | ||
| 135 | |||
| 136 | Result ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo( | ||
| 137 | Out<AppletIdentityInfo> out_identity_info) { | ||
| 138 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 139 | *out_identity_info = { | ||
| 140 | .applet_id = AppletId::QLaunch, | ||
| 141 | .application_id = 0x0100000000001000ull, | ||
| 142 | }; | ||
| 143 | R_SUCCEED(); | ||
| 144 | } | ||
| 145 | |||
| 146 | Result ILibraryAppletSelfAccessor::CanUseApplicationCore(Out<bool> out_can_use_application_core) { | ||
| 147 | // TODO: This appears to read the NPDM from state and check the core mask of the applet. | ||
| 148 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 149 | *out_can_use_application_core = false; | ||
| 150 | R_SUCCEED(); | ||
| 151 | } | ||
| 152 | |||
| 153 | Result ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty( | ||
| 154 | OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp) { | ||
| 155 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 156 | |||
| 157 | // TODO: this should be the main applet, not the caller applet | ||
| 158 | const auto application = GetCallerIdentity(*m_applet); | ||
| 159 | std::vector<u8> nacp; | ||
| 160 | const auto result = | ||
| 161 | system.GetARPManager().GetControlProperty(&nacp, application.application_id); | ||
| 162 | |||
| 163 | if (R_SUCCEEDED(result)) { | ||
| 164 | std::memcpy(out_nacp->data(), nacp.data(), std::min(nacp.size(), out_nacp->size())); | ||
| 165 | } | ||
| 166 | |||
| 167 | R_RETURN(result); | ||
| 168 | } | ||
| 169 | |||
| 170 | Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id) { | ||
| 171 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 172 | *out_storage_id = FileSys::StorageId::NandUser; | ||
| 173 | R_SUCCEED(); | ||
| 174 | } | ||
| 175 | |||
| 176 | Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() { | ||
| 177 | LOG_INFO(Service_AM, "called"); | ||
| 178 | system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid); | ||
| 179 | m_broker->SignalCompletion(); | ||
| 180 | R_SUCCEED(); | ||
| 181 | } | ||
| 182 | |||
| 183 | Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo( | ||
| 184 | Out<AppletIdentityInfo> out_identity_info) { | ||
| 185 | LOG_INFO(Service_AM, "called"); | ||
| 186 | *out_identity_info = GetCallerIdentity(*m_applet); | ||
| 187 | R_SUCCEED(); | ||
| 188 | } | ||
| 189 | |||
| 190 | Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack( | ||
| 191 | Out<s32> out_count, OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info) { | ||
| 192 | LOG_INFO(Service_AM, "called"); | ||
| 193 | |||
| 194 | std::shared_ptr<Applet> applet = m_applet; | ||
| 195 | *out_count = 0; | ||
| 196 | |||
| 197 | do { | ||
| 198 | if (*out_count >= static_cast<s32>(out_identity_info.size())) { | ||
| 199 | break; | ||
| 200 | } | ||
| 201 | out_identity_info[(*out_count)++] = GetCallerIdentity(*applet); | ||
| 202 | } while ((applet = applet->caller_applet.lock())); | ||
| 203 | |||
| 204 | R_SUCCEED(); | ||
| 205 | } | ||
| 206 | |||
| 207 | Result ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(Out<u32> out_desirable_layout) { | ||
| 208 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 209 | *out_desirable_layout = 0; | ||
| 210 | R_SUCCEED(); | ||
| 211 | } | ||
| 212 | |||
| 213 | Result ILibraryAppletSelfAccessor::ReportVisibleError(ErrorCode error_code) { | ||
| 214 | LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category, | ||
| 215 | error_code.number); | ||
| 216 | R_SUCCEED(); | ||
| 217 | } | ||
| 218 | |||
| 219 | Result ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext( | ||
| 220 | ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context) { | ||
| 221 | LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category, | ||
| 222 | error_code.number); | ||
| 223 | R_SUCCEED(); | ||
| 224 | } | ||
| 225 | |||
| 226 | Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage( | ||
| 227 | Out<u64> out_desired_language) { | ||
| 228 | // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage | ||
| 229 | // FIXME: all of this stuff belongs to ns | ||
| 230 | auto identity = GetCallerIdentity(*m_applet); | ||
| 231 | |||
| 232 | // TODO(bunnei): This should be configurable | ||
| 233 | LOG_DEBUG(Service_AM, "called"); | ||
| 234 | |||
| 235 | // Get supported languages from NACP, if possible | ||
| 236 | // Default to 0 (all languages supported) | ||
| 237 | u32 supported_languages = 0; | ||
| 238 | |||
| 239 | const auto res = [this, identity] { | ||
| 240 | const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(), | ||
| 241 | system.GetContentProvider()}; | ||
| 242 | auto metadata = pm.GetControlMetadata(); | ||
| 243 | if (metadata.first != nullptr) { | ||
| 244 | return metadata; | ||
| 245 | } | ||
| 246 | |||
| 247 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id), | ||
| 248 | system.GetFileSystemController(), | ||
| 249 | system.GetContentProvider()}; | ||
| 250 | return pm_update.GetControlMetadata(); | ||
| 251 | }(); | ||
| 252 | |||
| 253 | if (res.first != nullptr) { | ||
| 254 | supported_languages = res.first->GetSupportedLanguages(); | ||
| 255 | } | ||
| 256 | |||
| 257 | // Call IApplicationManagerInterface implementation. | ||
| 258 | auto& service_manager = system.ServiceManager(); | ||
| 259 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | ||
| 260 | auto app_man = ns_am2->GetApplicationManagerInterface(); | ||
| 261 | |||
| 262 | // Get desired application language | ||
| 263 | u8 desired_language{}; | ||
| 264 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); | ||
| 265 | |||
| 266 | // Convert to settings language code. | ||
| 267 | u64 language_code{}; | ||
| 268 | R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language)); | ||
| 269 | |||
| 270 | LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code); | ||
| 271 | |||
| 272 | *out_desired_language = language_code; | ||
| 273 | R_SUCCEED(); | ||
| 274 | } | ||
| 275 | |||
| 276 | Result ILibraryAppletSelfAccessor::GetCurrentApplicationId(Out<u64> out_application_id) { | ||
| 277 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 278 | |||
| 279 | // TODO: this should be the main applet, not the caller applet | ||
| 280 | const auto main_applet = GetCallerIdentity(*m_applet); | ||
| 281 | *out_application_id = main_applet.application_id; | ||
| 282 | |||
| 283 | R_SUCCEED(); | ||
| 284 | } | ||
| 285 | |||
| 286 | Result ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers( | ||
| 287 | Out<bool> out_no_users_available, Out<s32> out_users_count, | ||
| 288 | OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users) { | ||
| 289 | const Service::Account::ProfileManager manager{}; | ||
| 290 | |||
| 291 | *out_no_users_available = true; | ||
| 292 | *out_users_count = -1; | ||
| 293 | |||
| 294 | LOG_INFO(Service_AM, "called"); | ||
| 295 | |||
| 296 | if (manager.GetUserCount() > 0) { | ||
| 297 | *out_no_users_available = false; | ||
| 298 | *out_users_count = static_cast<s32>(manager.GetUserCount()); | ||
| 299 | |||
| 300 | const auto users = manager.GetAllUsers(); | ||
| 301 | for (size_t i = 0; i < users.size() && i < out_users.size(); i++) { | ||
| 302 | out_users[i] = users[i]; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | R_SUCCEED(); | ||
| 307 | } | ||
| 308 | |||
| 309 | Result ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually( | ||
| 310 | Out<bool> out_should_set_gpu_time_slice_manually) { | ||
| 311 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 312 | *out_should_set_gpu_time_slice_manually = false; | ||
| 313 | R_SUCCEED(); | ||
| 314 | } | ||
| 315 | |||
| 316 | Result ILibraryAppletSelfAccessor::Cmd160(Out<u64> out_unknown0) { | ||
| 317 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 318 | *out_unknown0 = 0; | ||
| 319 | R_SUCCEED(); | ||
| 320 | } | ||
| 321 | |||
| 322 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.h b/src/core/hle/service/am/service/library_applet_self_accessor.h new file mode 100644 index 000000000..a9743569f --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_self_accessor.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/uuid.h" | ||
| 7 | #include "core/hle/service/am/am_types.h" | ||
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace FileSys { | ||
| 12 | enum class StorageId : u8; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | class KReadableEvent; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | class AppletDataBroker; | ||
| 22 | struct Applet; | ||
| 23 | class IStorage; | ||
| 24 | |||
| 25 | struct LibraryAppletInfo { | ||
| 26 | AppletId applet_id; | ||
| 27 | LibraryAppletMode library_applet_mode; | ||
| 28 | }; | ||
| 29 | static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size."); | ||
| 30 | |||
| 31 | struct ErrorCode { | ||
| 32 | u32 category; | ||
| 33 | u32 number; | ||
| 34 | }; | ||
| 35 | static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size."); | ||
| 36 | |||
| 37 | struct ErrorContext { | ||
| 38 | u8 type; | ||
| 39 | INSERT_PADDING_BYTES_NOINIT(0x7); | ||
| 40 | std::array<u8, 0x1f4> data; | ||
| 41 | Result result; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size."); | ||
| 44 | |||
| 45 | class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { | ||
| 46 | public: | ||
| 47 | explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 48 | ~ILibraryAppletSelfAccessor() override; | ||
| 49 | |||
| 50 | private: | ||
| 51 | Result PopInData(Out<SharedPointer<IStorage>> out_storage); | ||
| 52 | Result PushOutData(SharedPointer<IStorage> storage); | ||
| 53 | Result PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage); | ||
| 54 | Result PushInteractiveOutData(SharedPointer<IStorage> storage); | ||
| 55 | Result GetPopInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 56 | Result GetPopInteractiveInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 57 | Result GetLibraryAppletInfo(Out<LibraryAppletInfo> out_library_applet_info); | ||
| 58 | Result GetMainAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info); | ||
| 59 | Result CanUseApplicationCore(Out<bool> out_can_use_application_core); | ||
| 60 | Result GetMainAppletApplicationControlProperty( | ||
| 61 | OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp); | ||
| 62 | Result GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id); | ||
| 63 | Result ExitProcessAndReturn(); | ||
| 64 | Result GetCallerAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info); | ||
| 65 | Result GetCallerAppletIdentityInfoStack( | ||
| 66 | Out<s32> out_count, | ||
| 67 | OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info); | ||
| 68 | Result GetDesirableKeyboardLayout(Out<u32> out_desirable_layout); | ||
| 69 | Result ReportVisibleError(ErrorCode error_code); | ||
| 70 | Result ReportVisibleErrorWithErrorContext( | ||
| 71 | ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context); | ||
| 72 | Result GetMainAppletApplicationDesiredLanguage(Out<u64> out_desired_language); | ||
| 73 | Result GetCurrentApplicationId(Out<u64> out_application_id); | ||
| 74 | Result GetMainAppletAvailableUsers(Out<bool> out_no_users_available, Out<s32> out_users_count, | ||
| 75 | OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users); | ||
| 76 | Result ShouldSetGpuTimeSliceManually(Out<bool> out_should_set_gpu_time_slice_manually); | ||
| 77 | Result Cmd160(Out<u64> out_unknown0); | ||
| 78 | |||
| 79 | const std::shared_ptr<Applet> m_applet; | ||
| 80 | const std::shared_ptr<AppletDataBroker> m_broker; | ||
| 81 | }; | ||
| 82 | |||
| 83 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/lock_accessor.cpp b/src/core/hle/service/am/service/lock_accessor.cpp new file mode 100644 index 000000000..8e556fdd6 --- /dev/null +++ b/src/core/hle/service/am/service/lock_accessor.cpp | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/lock_accessor.h" | ||
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | ILockAccessor::ILockAccessor(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ILockAccessor"}, m_context{system_, "ILockAccessor"}, | ||
| 11 | m_event{m_context} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {1, D<&ILockAccessor::TryLock>, "TryLock"}, | ||
| 15 | {2, D<&ILockAccessor::Unlock>, "Unlock"}, | ||
| 16 | {3, D<&ILockAccessor::GetEvent>, "GetEvent"}, | ||
| 17 | {4, D<&ILockAccessor::IsLocked>, "IsLocked"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | |||
| 23 | m_event.Signal(); | ||
| 24 | } | ||
| 25 | |||
| 26 | ILockAccessor::~ILockAccessor() = default; | ||
| 27 | |||
| 28 | Result ILockAccessor::TryLock(Out<bool> out_is_locked, | ||
| 29 | OutCopyHandle<Kernel::KReadableEvent> out_handle, | ||
| 30 | bool return_handle) { | ||
| 31 | LOG_INFO(Service_AM, "called, return_handle={}", return_handle); | ||
| 32 | |||
| 33 | { | ||
| 34 | std::scoped_lock lk{m_mutex}; | ||
| 35 | if (m_is_locked) { | ||
| 36 | *out_is_locked = false; | ||
| 37 | } else { | ||
| 38 | m_is_locked = true; | ||
| 39 | *out_is_locked = true; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | if (return_handle) { | ||
| 44 | *out_handle = m_event.GetHandle(); | ||
| 45 | } | ||
| 46 | |||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Result ILockAccessor::Unlock() { | ||
| 51 | LOG_INFO(Service_AM, "called"); | ||
| 52 | |||
| 53 | { | ||
| 54 | std::scoped_lock lk{m_mutex}; | ||
| 55 | m_is_locked = false; | ||
| 56 | } | ||
| 57 | |||
| 58 | m_event.Signal(); | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | Result ILockAccessor::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle) { | ||
| 63 | LOG_INFO(Service_AM, "called"); | ||
| 64 | *out_handle = m_event.GetHandle(); | ||
| 65 | R_SUCCEED(); | ||
| 66 | } | ||
| 67 | |||
| 68 | Result ILockAccessor::IsLocked(Out<bool> out_is_locked) { | ||
| 69 | LOG_INFO(Service_AM, "called"); | ||
| 70 | std::scoped_lock lk{m_mutex}; | ||
| 71 | *out_is_locked = m_is_locked; | ||
| 72 | R_SUCCEED(); | ||
| 73 | } | ||
| 74 | |||
| 75 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/lock_accessor.h b/src/core/hle/service/am/service/lock_accessor.h new file mode 100644 index 000000000..9bfb5c050 --- /dev/null +++ b/src/core/hle/service/am/service/lock_accessor.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/os/event.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::AM { | ||
| 12 | |||
| 13 | class ILockAccessor final : public ServiceFramework<ILockAccessor> { | ||
| 14 | public: | ||
| 15 | explicit ILockAccessor(Core::System& system_); | ||
| 16 | ~ILockAccessor() override; | ||
| 17 | |||
| 18 | private: | ||
| 19 | Result TryLock(Out<bool> out_is_locked, OutCopyHandle<Kernel::KReadableEvent> out_handle, | ||
| 20 | bool return_handle); | ||
| 21 | Result Unlock(); | ||
| 22 | Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle); | ||
| 23 | Result IsLocked(Out<bool> out_is_locked); | ||
| 24 | |||
| 25 | private: | ||
| 26 | KernelHelpers::ServiceContext m_context; | ||
| 27 | Event m_event; | ||
| 28 | std::mutex m_mutex{}; | ||
| 29 | bool m_is_locked{}; | ||
| 30 | }; | ||
| 31 | |||
| 32 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/process_winding_controller.cpp b/src/core/hle/service/am/service/process_winding_controller.cpp new file mode 100644 index 000000000..10df830d7 --- /dev/null +++ b/src/core/hle/service/am/service/process_winding_controller.cpp | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/frontend/applets.h" | ||
| 5 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
| 6 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IProcessWindingController::IProcessWindingController(Core::System& system_, | ||
| 12 | std::shared_ptr<Applet> applet) | ||
| 13 | : ServiceFramework{system_, "IProcessWindingController"}, m_applet{std::move(applet)} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"}, | ||
| 17 | {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"}, | ||
| 18 | {21, nullptr, "PushContext"}, | ||
| 19 | {22, nullptr, "PopContext"}, | ||
| 20 | {23, nullptr, "CancelWindingReservation"}, | ||
| 21 | {30, nullptr, "WindAndDoReserved"}, | ||
| 22 | {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, | ||
| 23 | {41, nullptr, "ReserveToStartAndWait"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | |||
| 30 | IProcessWindingController::~IProcessWindingController() = default; | ||
| 31 | |||
| 32 | Result IProcessWindingController::GetLaunchReason( | ||
| 33 | Out<AppletProcessLaunchReason> out_launch_reason) { | ||
| 34 | LOG_INFO(Service_AM, "called"); | ||
| 35 | *out_launch_reason = m_applet->launch_reason; | ||
| 36 | R_SUCCEED(); | ||
| 37 | } | ||
| 38 | |||
| 39 | Result IProcessWindingController::OpenCallingLibraryApplet( | ||
| 40 | Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet) { | ||
| 41 | LOG_INFO(Service_AM, "called"); | ||
| 42 | |||
| 43 | const auto caller_applet = m_applet->caller_applet.lock(); | ||
| 44 | if (caller_applet == nullptr) { | ||
| 45 | LOG_ERROR(Service_AM, "No caller applet available"); | ||
| 46 | R_THROW(ResultUnknown); | ||
| 47 | } | ||
| 48 | |||
| 49 | *out_calling_library_applet = std::make_shared<ILibraryAppletAccessor>( | ||
| 50 | system, m_applet->caller_applet_broker, caller_applet); | ||
| 51 | R_SUCCEED(); | ||
| 52 | } | ||
| 53 | |||
| 54 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/process_winding_controller.h b/src/core/hle/service/am/service/process_winding_controller.h index 71ae4c4f5..4408af1f1 100644 --- a/src/core/hle/service/am/process_winding_controller.h +++ b/src/core/hle/service/am/service/process_winding_controller.h | |||
| @@ -3,11 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/am/am_types.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 6 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 7 | 9 | ||
| 8 | namespace Service::AM { | 10 | namespace Service::AM { |
| 9 | 11 | ||
| 10 | struct Applet; | 12 | struct Applet; |
| 13 | class ILibraryAppletAccessor; | ||
| 11 | 14 | ||
| 12 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { | 15 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { |
| 13 | public: | 16 | public: |
| @@ -15,10 +18,11 @@ public: | |||
| 15 | ~IProcessWindingController() override; | 18 | ~IProcessWindingController() override; |
| 16 | 19 | ||
| 17 | private: | 20 | private: |
| 18 | void GetLaunchReason(HLERequestContext& ctx); | 21 | Result GetLaunchReason(Out<AppletProcessLaunchReason> out_launch_reason); |
| 19 | void OpenCallingLibraryApplet(HLERequestContext& ctx); | 22 | Result OpenCallingLibraryApplet( |
| 23 | Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet); | ||
| 20 | 24 | ||
| 21 | const std::shared_ptr<Applet> applet; | 25 | const std::shared_ptr<Applet> m_applet; |
| 22 | }; | 26 | }; |
| 23 | 27 | ||
| 24 | } // namespace Service::AM | 28 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp new file mode 100644 index 000000000..5c4c13de1 --- /dev/null +++ b/src/core/hle/service/am/service/self_controller.cpp | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/result.h" | ||
| 6 | #include "core/hle/service/am/am_results.h" | ||
| 7 | #include "core/hle/service/am/frontend/applets.h" | ||
| 8 | #include "core/hle/service/am/service/self_controller.h" | ||
| 9 | #include "core/hle/service/caps/caps_su.h" | ||
| 10 | #include "core/hle/service/cmif_serialization.h" | ||
| 11 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | #include "core/hle/service/vi/vi_results.h" | ||
| 14 | |||
| 15 | namespace Service::AM { | ||
| 16 | |||
| 17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 18 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | ||
| 19 | : ServiceFramework{system_, "ISelfController"}, | ||
| 20 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 21 | // clang-format off | ||
| 22 | static const FunctionInfo functions[] = { | ||
| 23 | {0, D<&ISelfController::Exit>, "Exit"}, | ||
| 24 | {1, D<&ISelfController::LockExit>, "LockExit"}, | ||
| 25 | {2, D<&ISelfController::UnlockExit>, "UnlockExit"}, | ||
| 26 | {3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"}, | ||
| 27 | {4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"}, | ||
| 28 | {9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"}, | ||
| 29 | {10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"}, | ||
| 30 | {11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"}, | ||
| 31 | {12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"}, | ||
| 32 | {13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"}, | ||
| 33 | {14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"}, | ||
| 34 | {15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"}, | ||
| 35 | {16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"}, | ||
| 36 | {17, nullptr, "SetControllerFirmwareUpdateSection"}, | ||
| 37 | {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"}, | ||
| 38 | {19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"}, | ||
| 39 | {20, nullptr, "SetDesirableKeyboardLayout"}, | ||
| 40 | {21, nullptr, "GetScreenShotProgramId"}, | ||
| 41 | {40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"}, | ||
| 42 | {41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"}, | ||
| 43 | {42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"}, | ||
| 44 | {43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"}, | ||
| 45 | {44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"}, | ||
| 46 | {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, | ||
| 47 | {46, nullptr, "SetRecordingLayerCompositionEnabled"}, | ||
| 48 | {50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"}, | ||
| 49 | {51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"}, | ||
| 50 | {60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"}, | ||
| 51 | {61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"}, | ||
| 52 | {62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"}, | ||
| 53 | {63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"}, | ||
| 54 | {64, nullptr, "SetInputDetectionSourceSet"}, | ||
| 55 | {65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"}, | ||
| 56 | {66, nullptr, "GetCurrentIlluminance"}, | ||
| 57 | {67, nullptr, "IsIlluminanceAvailable"}, | ||
| 58 | {68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"}, | ||
| 59 | {69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"}, | ||
| 60 | {70, nullptr, "ReportMultimediaError"}, | ||
| 61 | {71, nullptr, "GetCurrentIlluminanceEx"}, | ||
| 62 | {72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"}, | ||
| 63 | {80, nullptr, "SetWirelessPriorityMode"}, | ||
| 64 | {90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"}, | ||
| 65 | {91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"}, | ||
| 66 | {100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"}, | ||
| 67 | {110, nullptr, "SetApplicationAlbumUserData"}, | ||
| 68 | {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, | ||
| 69 | {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, | ||
| 70 | {1000, nullptr, "GetDebugStorageChannel"}, | ||
| 71 | }; | ||
| 72 | // clang-format on | ||
| 73 | |||
| 74 | RegisterHandlers(functions); | ||
| 75 | } | ||
| 76 | |||
| 77 | ISelfController::~ISelfController() = default; | ||
| 78 | |||
| 79 | Result ISelfController::Exit() { | ||
| 80 | LOG_DEBUG(Service_AM, "called"); | ||
| 81 | |||
| 82 | // TODO | ||
| 83 | system.Exit(); | ||
| 84 | |||
| 85 | R_SUCCEED(); | ||
| 86 | } | ||
| 87 | |||
| 88 | Result ISelfController::LockExit() { | ||
| 89 | LOG_DEBUG(Service_AM, "called"); | ||
| 90 | |||
| 91 | system.SetExitLocked(true); | ||
| 92 | |||
| 93 | R_SUCCEED(); | ||
| 94 | } | ||
| 95 | |||
| 96 | Result ISelfController::UnlockExit() { | ||
| 97 | LOG_DEBUG(Service_AM, "called"); | ||
| 98 | |||
| 99 | system.SetExitLocked(false); | ||
| 100 | |||
| 101 | if (system.GetExitRequested()) { | ||
| 102 | system.Exit(); | ||
| 103 | } | ||
| 104 | |||
| 105 | R_SUCCEED(); | ||
| 106 | } | ||
| 107 | |||
| 108 | Result ISelfController::EnterFatalSection() { | ||
| 109 | std::scoped_lock lk{m_applet->lock}; | ||
| 110 | |||
| 111 | m_applet->fatal_section_count++; | ||
| 112 | LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", m_applet->fatal_section_count); | ||
| 113 | |||
| 114 | R_SUCCEED(); | ||
| 115 | } | ||
| 116 | |||
| 117 | Result ISelfController::LeaveFatalSection() { | ||
| 118 | LOG_DEBUG(Service_AM, "called"); | ||
| 119 | |||
| 120 | // Entry and exit of fatal sections must be balanced. | ||
| 121 | std::scoped_lock lk{m_applet->lock}; | ||
| 122 | R_UNLESS(m_applet->fatal_section_count > 0, AM::ResultFatalSectionCountImbalance); | ||
| 123 | m_applet->fatal_section_count--; | ||
| 124 | |||
| 125 | R_SUCCEED(); | ||
| 126 | } | ||
| 127 | |||
| 128 | Result ISelfController::GetLibraryAppletLaunchableEvent( | ||
| 129 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 130 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 131 | |||
| 132 | m_applet->library_applet_launchable_event.Signal(); | ||
| 133 | *out_event = m_applet->library_applet_launchable_event.GetHandle(); | ||
| 134 | |||
| 135 | R_SUCCEED(); | ||
| 136 | } | ||
| 137 | |||
| 138 | Result ISelfController::SetScreenShotPermission(ScreenshotPermission screen_shot_permission) { | ||
| 139 | LOG_DEBUG(Service_AM, "called, permission={}", screen_shot_permission); | ||
| 140 | |||
| 141 | std::scoped_lock lk{m_applet->lock}; | ||
| 142 | m_applet->screenshot_permission = screen_shot_permission; | ||
| 143 | |||
| 144 | R_SUCCEED(); | ||
| 145 | } | ||
| 146 | |||
| 147 | Result ISelfController::SetOperationModeChangedNotification(bool enabled) { | ||
| 148 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
| 149 | |||
| 150 | std::scoped_lock lk{m_applet->lock}; | ||
| 151 | m_applet->operation_mode_changed_notification_enabled = enabled; | ||
| 152 | |||
| 153 | R_SUCCEED(); | ||
| 154 | } | ||
| 155 | |||
| 156 | Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) { | ||
| 157 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
| 158 | |||
| 159 | std::scoped_lock lk{m_applet->lock}; | ||
| 160 | m_applet->performance_mode_changed_notification_enabled = enabled; | ||
| 161 | |||
| 162 | R_SUCCEED(); | ||
| 163 | } | ||
| 164 | |||
| 165 | Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) { | ||
| 166 | LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify, | ||
| 167 | background, suspend); | ||
| 168 | |||
| 169 | std::scoped_lock lk{m_applet->lock}; | ||
| 170 | m_applet->focus_handling_mode = {notify, background, suspend}; | ||
| 171 | |||
| 172 | R_SUCCEED(); | ||
| 173 | } | ||
| 174 | |||
| 175 | Result ISelfController::SetRestartMessageEnabled(bool enabled) { | ||
| 176 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
| 177 | |||
| 178 | std::scoped_lock lk{m_applet->lock}; | ||
| 179 | m_applet->restart_message_enabled = enabled; | ||
| 180 | |||
| 181 | R_SUCCEED(); | ||
| 182 | } | ||
| 183 | |||
| 184 | Result ISelfController::SetScreenShotAppletIdentityInfo( | ||
| 185 | AppletIdentityInfo screen_shot_applet_identity_info) { | ||
| 186 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 187 | |||
| 188 | std::scoped_lock lk{m_applet->lock}; | ||
| 189 | m_applet->screen_shot_identity = screen_shot_applet_identity_info; | ||
| 190 | |||
| 191 | R_SUCCEED(); | ||
| 192 | } | ||
| 193 | |||
| 194 | Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) { | ||
| 195 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
| 196 | |||
| 197 | std::scoped_lock lk{m_applet->lock}; | ||
| 198 | m_applet->out_of_focus_suspension_enabled = enabled; | ||
| 199 | |||
| 200 | R_SUCCEED(); | ||
| 201 | } | ||
| 202 | |||
| 203 | Result ISelfController::SetAlbumImageOrientation( | ||
| 204 | Capture::AlbumImageOrientation album_image_orientation) { | ||
| 205 | LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", album_image_orientation); | ||
| 206 | |||
| 207 | std::scoped_lock lk{m_applet->lock}; | ||
| 208 | m_applet->album_image_orientation = album_image_orientation; | ||
| 209 | |||
| 210 | R_SUCCEED(); | ||
| 211 | } | ||
| 212 | |||
| 213 | Result ISelfController::IsSystemBufferSharingEnabled() { | ||
| 214 | LOG_INFO(Service_AM, "called"); | ||
| 215 | R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize( | ||
| 216 | &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode)); | ||
| 217 | R_THROW(VI::ResultOperationFailed); | ||
| 218 | } | ||
| 219 | |||
| 220 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { | ||
| 221 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 222 | |||
| 223 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 224 | |||
| 225 | u64 layer_id; | ||
| 226 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id); | ||
| 227 | R_SUCCEED(); | ||
| 228 | } | ||
| 229 | |||
| 230 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { | ||
| 231 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
| 232 | |||
| 233 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 234 | |||
| 235 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id); | ||
| 236 | R_SUCCEED(); | ||
| 237 | } | ||
| 238 | |||
| 239 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { | ||
| 240 | LOG_INFO(Service_AM, "called"); | ||
| 241 | |||
| 242 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | ||
| 243 | m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id); | ||
| 244 | |||
| 245 | R_SUCCEED(); | ||
| 246 | } | ||
| 247 | |||
| 248 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | ||
| 249 | Out<u64> out_recording_layer_id) { | ||
| 250 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 251 | |||
| 252 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | ||
| 253 | m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id, | ||
| 254 | out_recording_layer_id); | ||
| 255 | |||
| 256 | R_SUCCEED(); | ||
| 257 | } | ||
| 258 | |||
| 259 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { | ||
| 260 | LOG_WARNING(Service_AM, "(STUBBED) called, enable={}", enable); | ||
| 261 | R_SUCCEED(); | ||
| 262 | } | ||
| 263 | |||
| 264 | Result ISelfController::ApproveToDisplay() { | ||
| 265 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 266 | R_SUCCEED(); | ||
| 267 | } | ||
| 268 | |||
| 269 | Result ISelfController::SetMediaPlaybackState(bool state) { | ||
| 270 | LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state); | ||
| 271 | R_SUCCEED(); | ||
| 272 | } | ||
| 273 | |||
| 274 | Result ISelfController::OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d) { | ||
| 275 | LOG_WARNING(Service_AM, "(STUBBED) called, a={}, b={}, c={}, d={}", a, b, c, d); | ||
| 276 | R_SUCCEED(); | ||
| 277 | } | ||
| 278 | |||
| 279 | Result ISelfController::SetIdleTimeDetectionExtension( | ||
| 280 | IdleTimeDetectionExtension idle_time_detection_extension) { | ||
| 281 | LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", idle_time_detection_extension); | ||
| 282 | |||
| 283 | std::scoped_lock lk{m_applet->lock}; | ||
| 284 | m_applet->idle_time_detection_extension = idle_time_detection_extension; | ||
| 285 | |||
| 286 | R_SUCCEED(); | ||
| 287 | } | ||
| 288 | |||
| 289 | Result ISelfController::GetIdleTimeDetectionExtension( | ||
| 290 | Out<IdleTimeDetectionExtension> out_idle_time_detection_extension) { | ||
| 291 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 292 | |||
| 293 | std::scoped_lock lk{m_applet->lock}; | ||
| 294 | *out_idle_time_detection_extension = m_applet->idle_time_detection_extension; | ||
| 295 | |||
| 296 | R_SUCCEED(); | ||
| 297 | } | ||
| 298 | |||
| 299 | Result ISelfController::ReportUserIsActive() { | ||
| 300 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 301 | R_SUCCEED(); | ||
| 302 | } | ||
| 303 | |||
| 304 | Result ISelfController::SetAutoSleepDisabled(bool is_auto_sleep_disabled) { | ||
| 305 | LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled); | ||
| 306 | |||
| 307 | // On the system itself, if the previous state of is_auto_sleep_disabled | ||
| 308 | // differed from the current value passed in, it'd signify the internal | ||
| 309 | // window manager to update (and also increment some statistics like update counts) | ||
| 310 | // | ||
| 311 | // It'd also indicate this change to an idle handling context. | ||
| 312 | // | ||
| 313 | // However, given we're emulating this behavior, most of this can be ignored | ||
| 314 | // and it's sufficient to simply set the member variable for querying via | ||
| 315 | // IsAutoSleepDisabled(). | ||
| 316 | |||
| 317 | std::scoped_lock lk{m_applet->lock}; | ||
| 318 | m_applet->auto_sleep_disabled = is_auto_sleep_disabled; | ||
| 319 | |||
| 320 | R_SUCCEED(); | ||
| 321 | } | ||
| 322 | |||
| 323 | Result ISelfController::IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled) { | ||
| 324 | LOG_DEBUG(Service_AM, "called."); | ||
| 325 | |||
| 326 | std::scoped_lock lk{m_applet->lock}; | ||
| 327 | *out_is_auto_sleep_disabled = m_applet->auto_sleep_disabled; | ||
| 328 | |||
| 329 | R_SUCCEED(); | ||
| 330 | } | ||
| 331 | |||
| 332 | Result ISelfController::SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy) { | ||
| 333 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 334 | R_SUCCEED(); | ||
| 335 | } | ||
| 336 | |||
| 337 | Result ISelfController::GetAccumulatedSuspendedTickValue( | ||
| 338 | Out<u64> out_accumulated_suspended_tick_value) { | ||
| 339 | LOG_DEBUG(Service_AM, "called."); | ||
| 340 | |||
| 341 | // This command returns the total number of system ticks since ISelfController creation | ||
| 342 | // where the game was suspended. Since Yuzu doesn't implement game suspension, this command | ||
| 343 | // can just always return 0 ticks. | ||
| 344 | std::scoped_lock lk{m_applet->lock}; | ||
| 345 | *out_accumulated_suspended_tick_value = m_applet->suspended_ticks; | ||
| 346 | |||
| 347 | R_SUCCEED(); | ||
| 348 | } | ||
| 349 | |||
| 350 | Result ISelfController::GetAccumulatedSuspendedTickChangedEvent( | ||
| 351 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 352 | LOG_DEBUG(Service_AM, "called."); | ||
| 353 | |||
| 354 | *out_event = m_applet->accumulated_suspended_tick_changed_event.GetHandle(); | ||
| 355 | R_SUCCEED(); | ||
| 356 | } | ||
| 357 | |||
| 358 | Result ISelfController::SetAlbumImageTakenNotificationEnabled(bool enabled) { | ||
| 359 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
| 360 | |||
| 361 | // This service call sets an internal flag whether a notification is shown when an image is | ||
| 362 | // captured. Currently we do not support capturing images via the capture button, so this can be | ||
| 363 | // stubbed for now. | ||
| 364 | std::scoped_lock lk{m_applet->lock}; | ||
| 365 | m_applet->album_image_taken_notification_enabled = enabled; | ||
| 366 | |||
| 367 | R_SUCCEED(); | ||
| 368 | } | ||
| 369 | |||
| 370 | Result ISelfController::SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option) { | ||
| 371 | LOG_INFO(Service_AM, "called, report_option={}", album_report_option); | ||
| 372 | |||
| 373 | const auto screenshot_service = | ||
| 374 | system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>( | ||
| 375 | "caps:su"); | ||
| 376 | |||
| 377 | if (screenshot_service) { | ||
| 378 | screenshot_service->CaptureAndSaveScreenshot(album_report_option); | ||
| 379 | } | ||
| 380 | |||
| 381 | R_SUCCEED(); | ||
| 382 | } | ||
| 383 | |||
| 384 | Result ISelfController::SetRecordVolumeMuted(bool muted) { | ||
| 385 | LOG_WARNING(Service_AM, "(STUBBED) called. muted={}", muted); | ||
| 386 | |||
| 387 | std::scoped_lock lk{m_applet->lock}; | ||
| 388 | m_applet->record_volume_muted = muted; | ||
| 389 | |||
| 390 | R_SUCCEED(); | ||
| 391 | } | ||
| 392 | |||
| 393 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h new file mode 100644 index 000000000..01fa381a3 --- /dev/null +++ b/src/core/hle/service/am/service/self_controller.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/am/am_types.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | class KReadableEvent; | ||
| 12 | } | ||
| 13 | |||
| 14 | namespace Service::Capture { | ||
| 15 | enum class AlbumImageOrientation; | ||
| 16 | enum class AlbumReportOption; | ||
| 17 | } // namespace Service::Capture | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | struct Applet; | ||
| 22 | |||
| 23 | class ISelfController final : public ServiceFramework<ISelfController> { | ||
| 24 | public: | ||
| 25 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 26 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
| 27 | ~ISelfController() override; | ||
| 28 | |||
| 29 | private: | ||
| 30 | Result Exit(); | ||
| 31 | Result LockExit(); | ||
| 32 | Result UnlockExit(); | ||
| 33 | Result EnterFatalSection(); | ||
| 34 | Result LeaveFatalSection(); | ||
| 35 | Result GetLibraryAppletLaunchableEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 36 | Result SetScreenShotPermission(ScreenshotPermission screen_shot_permission); | ||
| 37 | Result SetOperationModeChangedNotification(bool enabled); | ||
| 38 | Result SetPerformanceModeChangedNotification(bool enabled); | ||
| 39 | Result SetFocusHandlingMode(bool notify, bool background, bool suspend); | ||
| 40 | Result SetRestartMessageEnabled(bool enabled); | ||
| 41 | Result SetScreenShotAppletIdentityInfo(AppletIdentityInfo screen_shot_applet_identity_info); | ||
| 42 | Result SetOutOfFocusSuspendingEnabled(bool enabled); | ||
| 43 | Result SetAlbumImageOrientation(Capture::AlbumImageOrientation album_image_orientation); | ||
| 44 | Result IsSystemBufferSharingEnabled(); | ||
| 45 | Result GetSystemSharedBufferHandle(Out<u64> out_buffer_id); | ||
| 46 | Result GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id); | ||
| 47 | Result CreateManagedDisplayLayer(Out<u64> out_layer_id); | ||
| 48 | Result CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | ||
| 49 | Out<u64> out_recording_layer_id); | ||
| 50 | Result SetHandlesRequestToDisplay(bool enable); | ||
| 51 | Result ApproveToDisplay(); | ||
| 52 | Result SetMediaPlaybackState(bool state); | ||
| 53 | Result OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d); | ||
| 54 | Result SetIdleTimeDetectionExtension(IdleTimeDetectionExtension idle_time_detection_extension); | ||
| 55 | Result GetIdleTimeDetectionExtension( | ||
| 56 | Out<IdleTimeDetectionExtension> out_idle_time_detection_extension); | ||
| 57 | Result ReportUserIsActive(); | ||
| 58 | Result SetAutoSleepDisabled(bool is_auto_sleep_disabled); | ||
| 59 | Result IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled); | ||
| 60 | Result SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy); | ||
| 61 | Result GetAccumulatedSuspendedTickValue(Out<u64> out_accumulated_suspended_tick_value); | ||
| 62 | Result GetAccumulatedSuspendedTickChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 63 | Result SetAlbumImageTakenNotificationEnabled(bool enabled); | ||
| 64 | Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); | ||
| 65 | Result SetRecordVolumeMuted(bool muted); | ||
| 66 | |||
| 67 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 68 | Kernel::KProcess* const m_process; | ||
| 69 | const std::shared_ptr<Applet> m_applet; | ||
| 70 | }; | ||
| 71 | |||
| 72 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/storage.cpp b/src/core/hle/service/am/service/storage.cpp new file mode 100644 index 000000000..25ee0afbd --- /dev/null +++ b/src/core/hle/service/am/service/storage.cpp | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/am_results.h" | ||
| 5 | #include "core/hle/service/am/library_applet_storage.h" | ||
| 6 | #include "core/hle/service/am/service/storage.h" | ||
| 7 | #include "core/hle/service/am/service/storage_accessor.h" | ||
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) | ||
| 13 | : ServiceFramework{system_, "IStorage"}, m_impl{std::move(impl)} { | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, D<&IStorage::Open>, "Open"}, | ||
| 16 | {1, D<&IStorage::OpenTransferStorage>, "OpenTransferStorage"}, | ||
| 17 | }; | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IStorage::IStorage(Core::System& system_, std::vector<u8>&& data) | ||
| 23 | : IStorage(system_, CreateStorage(std::move(data))) {} | ||
| 24 | |||
| 25 | IStorage::~IStorage() = default; | ||
| 26 | |||
| 27 | Result IStorage::Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor) { | ||
| 28 | LOG_DEBUG(Service_AM, "called"); | ||
| 29 | |||
| 30 | R_UNLESS(m_impl->GetHandle() == nullptr, AM::ResultInvalidStorageType); | ||
| 31 | |||
| 32 | *out_storage_accessor = std::make_shared<IStorageAccessor>(system, m_impl); | ||
| 33 | R_SUCCEED(); | ||
| 34 | } | ||
| 35 | |||
| 36 | Result IStorage::OpenTransferStorage( | ||
| 37 | Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor) { | ||
| 38 | R_UNLESS(m_impl->GetHandle() != nullptr, AM::ResultInvalidStorageType); | ||
| 39 | |||
| 40 | *out_transfer_storage_accessor = std::make_shared<ITransferStorageAccessor>(system, m_impl); | ||
| 41 | R_SUCCEED(); | ||
| 42 | } | ||
| 43 | |||
| 44 | std::vector<u8> IStorage::GetData() const { | ||
| 45 | return m_impl->GetData(); | ||
| 46 | } | ||
| 47 | |||
| 48 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/storage.h b/src/core/hle/service/am/service/storage.h index 10d00b141..cde2ed0ea 100644 --- a/src/core/hle/service/am/storage.h +++ b/src/core/hle/service/am/service/storage.h | |||
| @@ -3,29 +3,33 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 6 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 7 | 8 | ||
| 8 | namespace Service::AM { | 9 | namespace Service::AM { |
| 9 | 10 | ||
| 10 | class LibraryAppletStorage; | 11 | class LibraryAppletStorage; |
| 12 | class IStorageAccessor; | ||
| 13 | class ITransferStorageAccessor; | ||
| 11 | 14 | ||
| 12 | class IStorage final : public ServiceFramework<IStorage> { | 15 | class IStorage final : public ServiceFramework<IStorage> { |
| 13 | public: | 16 | public: |
| 14 | explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_); | 17 | explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl); |
| 15 | explicit IStorage(Core::System& system_, std::vector<u8>&& buffer); | 18 | explicit IStorage(Core::System& system_, std::vector<u8>&& buffer); |
| 16 | ~IStorage() override; | 19 | ~IStorage() override; |
| 17 | 20 | ||
| 18 | std::shared_ptr<LibraryAppletStorage> GetImpl() const { | 21 | std::shared_ptr<LibraryAppletStorage> GetImpl() const { |
| 19 | return impl; | 22 | return m_impl; |
| 20 | } | 23 | } |
| 21 | 24 | ||
| 22 | std::vector<u8> GetData() const; | 25 | std::vector<u8> GetData() const; |
| 23 | 26 | ||
| 24 | private: | 27 | private: |
| 25 | void Open(HLERequestContext& ctx); | 28 | Result Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor); |
| 26 | void OpenTransferStorage(HLERequestContext& ctx); | 29 | Result OpenTransferStorage( |
| 30 | Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor); | ||
| 27 | 31 | ||
| 28 | const std::shared_ptr<LibraryAppletStorage> impl; | 32 | const std::shared_ptr<LibraryAppletStorage> m_impl; |
| 29 | }; | 33 | }; |
| 30 | 34 | ||
| 31 | } // namespace Service::AM | 35 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/storage_accessor.cpp b/src/core/hle/service/am/service/storage_accessor.cpp new file mode 100644 index 000000000..84577fee4 --- /dev/null +++ b/src/core/hle/service/am/service/storage_accessor.cpp | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 5 | #include "core/hle/service/am/library_applet_storage.h" | ||
| 6 | #include "core/hle/service/am/service/storage_accessor.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IStorageAccessor::IStorageAccessor(Core::System& system_, | ||
| 12 | std::shared_ptr<LibraryAppletStorage> impl) | ||
| 13 | : ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} { | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, D<&IStorageAccessor::GetSize>, "GetSize"}, | ||
| 16 | {10, D<&IStorageAccessor::Write>, "Write"}, | ||
| 17 | {11, D<&IStorageAccessor::Read>, "Read"}, | ||
| 18 | }; | ||
| 19 | |||
| 20 | RegisterHandlers(functions); | ||
| 21 | } | ||
| 22 | |||
| 23 | IStorageAccessor::~IStorageAccessor() = default; | ||
| 24 | |||
| 25 | Result IStorageAccessor::GetSize(Out<s64> out_size) { | ||
| 26 | LOG_DEBUG(Service_AM, "called"); | ||
| 27 | *out_size = m_impl->GetSize(); | ||
| 28 | R_SUCCEED(); | ||
| 29 | } | ||
| 30 | |||
| 31 | Result IStorageAccessor::Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) { | ||
| 32 | LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size()); | ||
| 33 | R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size())); | ||
| 34 | } | ||
| 35 | |||
| 36 | Result IStorageAccessor::Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) { | ||
| 37 | LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size()); | ||
| 38 | R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size())); | ||
| 39 | } | ||
| 40 | |||
| 41 | ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_, | ||
| 42 | std::shared_ptr<LibraryAppletStorage> impl) | ||
| 43 | : ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} { | ||
| 44 | static const FunctionInfo functions[] = { | ||
| 45 | {0, D<&ITransferStorageAccessor::GetSize>, "GetSize"}, | ||
| 46 | {1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"}, | ||
| 47 | }; | ||
| 48 | |||
| 49 | RegisterHandlers(functions); | ||
| 50 | } | ||
| 51 | |||
| 52 | ITransferStorageAccessor::~ITransferStorageAccessor() = default; | ||
| 53 | |||
| 54 | Result ITransferStorageAccessor::GetSize(Out<s64> out_size) { | ||
| 55 | LOG_DEBUG(Service_AM, "called"); | ||
| 56 | *out_size = m_impl->GetSize(); | ||
| 57 | R_SUCCEED(); | ||
| 58 | } | ||
| 59 | |||
| 60 | Result ITransferStorageAccessor::GetHandle(Out<s64> out_size, | ||
| 61 | OutCopyHandle<Kernel::KTransferMemory> out_handle) { | ||
| 62 | LOG_INFO(Service_AM, "called"); | ||
| 63 | *out_size = m_impl->GetSize(); | ||
| 64 | *out_handle = m_impl->GetHandle(); | ||
| 65 | R_SUCCEED(); | ||
| 66 | } | ||
| 67 | |||
| 68 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/storage_accessor.h b/src/core/hle/service/am/service/storage_accessor.h index b9aa85a66..1a01730e0 100644 --- a/src/core/hle/service/am/storage_accessor.h +++ b/src/core/hle/service/am/service/storage_accessor.h | |||
| @@ -3,35 +3,36 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/am/storage.h" | 6 | #include "core/hle/service/am/library_applet_storage.h" |
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | 9 | ||
| 9 | namespace Service::AM { | 10 | namespace Service::AM { |
| 10 | 11 | ||
| 11 | class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { | 12 | class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { |
| 12 | public: | 13 | public: |
| 13 | explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_); | 14 | explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl); |
| 14 | ~IStorageAccessor() override; | 15 | ~IStorageAccessor() override; |
| 15 | 16 | ||
| 16 | private: | 17 | private: |
| 17 | void GetSize(HLERequestContext& ctx); | 18 | Result GetSize(Out<s64> out_size); |
| 18 | void Write(HLERequestContext& ctx); | 19 | Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset); |
| 19 | void Read(HLERequestContext& ctx); | 20 | Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset); |
| 20 | 21 | ||
| 21 | const std::shared_ptr<LibraryAppletStorage> impl; | 22 | const std::shared_ptr<LibraryAppletStorage> m_impl; |
| 22 | }; | 23 | }; |
| 23 | 24 | ||
| 24 | class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> { | 25 | class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> { |
| 25 | public: | 26 | public: |
| 26 | explicit ITransferStorageAccessor(Core::System& system_, | 27 | explicit ITransferStorageAccessor(Core::System& system_, |
| 27 | std::shared_ptr<LibraryAppletStorage> impl_); | 28 | std::shared_ptr<LibraryAppletStorage> impl); |
| 28 | ~ITransferStorageAccessor() override; | 29 | ~ITransferStorageAccessor() override; |
| 29 | 30 | ||
| 30 | private: | 31 | private: |
| 31 | void GetSize(HLERequestContext& ctx); | 32 | Result GetSize(Out<s64> out_size); |
| 32 | void GetHandle(HLERequestContext& ctx); | 33 | Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle); |
| 33 | 34 | ||
| 34 | const std::shared_ptr<LibraryAppletStorage> impl; | 35 | const std::shared_ptr<LibraryAppletStorage> m_impl; |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | } // namespace Service::AM | 38 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp new file mode 100644 index 000000000..5ec509d2e --- /dev/null +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/service/application_creator.h" | ||
| 6 | #include "core/hle/service/am/service/audio_controller.h" | ||
| 7 | #include "core/hle/service/am/service/common_state_getter.h" | ||
| 8 | #include "core/hle/service/am/service/debug_functions.h" | ||
| 9 | #include "core/hle/service/am/service/display_controller.h" | ||
| 10 | #include "core/hle/service/am/service/global_state_controller.h" | ||
| 11 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
| 12 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
| 13 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
| 14 | #include "core/hle/service/am/service/self_controller.h" | ||
| 15 | #include "core/hle/service/am/service/system_applet_proxy.h" | ||
| 16 | #include "core/hle/service/am/service/window_controller.h" | ||
| 17 | #include "core/hle/service/cmif_serialization.h" | ||
| 18 | |||
| 19 | namespace Service::AM { | ||
| 20 | |||
| 21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
| 22 | Kernel::KProcess* process, | ||
| 23 | Nvnflinger::Nvnflinger& nvnflinger) | ||
| 24 | : ServiceFramework{system_, "ISystemAppletProxy"}, | ||
| 25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 26 | // clang-format off | ||
| 27 | static const FunctionInfo functions[] = { | ||
| 28 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
| 29 | {1, D<&ISystemAppletProxy::GetSelfController>, "GetSelfController"}, | ||
| 30 | {2, D<&ISystemAppletProxy::GetWindowController>, "GetWindowController"}, | ||
| 31 | {3, D<&ISystemAppletProxy::GetAudioController>, "GetAudioController"}, | ||
| 32 | {4, D<&ISystemAppletProxy::GetDisplayController>, "GetDisplayController"}, | ||
| 33 | {10, D<&ISystemAppletProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
| 34 | {11, D<&ISystemAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
| 35 | {20, D<&ISystemAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"}, | ||
| 36 | {21, D<&ISystemAppletProxy::GetGlobalStateController>, "GetGlobalStateController"}, | ||
| 37 | {22, D<&ISystemAppletProxy::GetApplicationCreator>, "GetApplicationCreator"}, | ||
| 38 | {23, D<&ISystemAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"}, | ||
| 39 | {1000, D<&ISystemAppletProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | |||
| 46 | ISystemAppletProxy::~ISystemAppletProxy() = default; | ||
| 47 | |||
| 48 | Result ISystemAppletProxy::GetAudioController( | ||
| 49 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
| 50 | LOG_DEBUG(Service_AM, "called"); | ||
| 51 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
| 52 | R_SUCCEED(); | ||
| 53 | } | ||
| 54 | |||
| 55 | Result ISystemAppletProxy::GetDisplayController( | ||
| 56 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
| 57 | LOG_DEBUG(Service_AM, "called"); | ||
| 58 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | Result ISystemAppletProxy::GetProcessWindingController( | ||
| 63 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
| 64 | LOG_DEBUG(Service_AM, "called"); | ||
| 65 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
| 66 | R_SUCCEED(); | ||
| 67 | } | ||
| 68 | |||
| 69 | Result ISystemAppletProxy::GetDebugFunctions( | ||
| 70 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
| 71 | LOG_DEBUG(Service_AM, "called"); | ||
| 72 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
| 73 | R_SUCCEED(); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result ISystemAppletProxy::GetWindowController( | ||
| 77 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
| 78 | LOG_DEBUG(Service_AM, "called"); | ||
| 79 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
| 80 | R_SUCCEED(); | ||
| 81 | } | ||
| 82 | |||
| 83 | Result ISystemAppletProxy::GetSelfController( | ||
| 84 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
| 85 | LOG_DEBUG(Service_AM, "called"); | ||
| 86 | *out_self_controller = | ||
| 87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 88 | R_SUCCEED(); | ||
| 89 | } | ||
| 90 | |||
| 91 | Result ISystemAppletProxy::GetCommonStateGetter( | ||
| 92 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
| 93 | LOG_DEBUG(Service_AM, "called"); | ||
| 94 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
| 95 | R_SUCCEED(); | ||
| 96 | } | ||
| 97 | |||
| 98 | Result ISystemAppletProxy::GetLibraryAppletCreator( | ||
| 99 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
| 100 | LOG_DEBUG(Service_AM, "called"); | ||
| 101 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
| 102 | R_SUCCEED(); | ||
| 103 | } | ||
| 104 | |||
| 105 | Result ISystemAppletProxy::GetApplicationCreator( | ||
| 106 | Out<SharedPointer<IApplicationCreator>> out_application_creator) { | ||
| 107 | LOG_DEBUG(Service_AM, "called"); | ||
| 108 | *out_application_creator = std::make_shared<IApplicationCreator>(system); | ||
| 109 | R_SUCCEED(); | ||
| 110 | } | ||
| 111 | |||
| 112 | Result ISystemAppletProxy::GetAppletCommonFunctions( | ||
| 113 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) { | ||
| 114 | LOG_DEBUG(Service_AM, "called"); | ||
| 115 | *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet); | ||
| 116 | R_SUCCEED(); | ||
| 117 | } | ||
| 118 | |||
| 119 | Result ISystemAppletProxy::GetHomeMenuFunctions( | ||
| 120 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | ||
| 121 | LOG_DEBUG(Service_AM, "called"); | ||
| 122 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | ||
| 123 | R_SUCCEED(); | ||
| 124 | } | ||
| 125 | |||
| 126 | Result ISystemAppletProxy::GetGlobalStateController( | ||
| 127 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller) { | ||
| 128 | LOG_DEBUG(Service_AM, "called"); | ||
| 129 | *out_global_state_controller = std::make_shared<IGlobalStateController>(system); | ||
| 130 | R_SUCCEED(); | ||
| 131 | } | ||
| 132 | |||
| 133 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h new file mode 100644 index 000000000..3d5040315 --- /dev/null +++ b/src/core/hle/service/am/service/system_applet_proxy.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | class IAppletCommonFunctions; | ||
| 13 | class IApplicationCreator; | ||
| 14 | class IAudioController; | ||
| 15 | class ICommonStateGetter; | ||
| 16 | class IDebugFunctions; | ||
| 17 | class IDisplayController; | ||
| 18 | class IHomeMenuFunctions; | ||
| 19 | class IGlobalStateController; | ||
| 20 | class ILibraryAppletCreator; | ||
| 21 | class IProcessWindingController; | ||
| 22 | class ISelfController; | ||
| 23 | class IWindowController; | ||
| 24 | |||
| 25 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | ||
| 26 | public: | ||
| 27 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, | ||
| 28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
| 29 | ~ISystemAppletProxy(); | ||
| 30 | |||
| 31 | private: | ||
| 32 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
| 33 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
| 34 | Result GetProcessWindingController( | ||
| 35 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
| 36 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
| 37 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
| 38 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
| 39 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
| 40 | Result GetLibraryAppletCreator( | ||
| 41 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
| 42 | Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator); | ||
| 43 | Result GetAppletCommonFunctions( | ||
| 44 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions); | ||
| 45 | Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions); | ||
| 46 | Result GetGlobalStateController( | ||
| 47 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | ||
| 48 | |||
| 49 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 50 | Kernel::KProcess* const m_process; | ||
| 51 | const std::shared_ptr<Applet> m_applet; | ||
| 52 | }; | ||
| 53 | |||
| 54 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp new file mode 100644 index 000000000..b874ecb91 --- /dev/null +++ b/src/core/hle/service/am/service/window_controller.cpp | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet.h" | ||
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 6 | #include "core/hle/service/am/service/window_controller.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet) | ||
| 12 | : ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, nullptr, "CreateWindow"}, | ||
| 16 | {1, D<&IWindowController::GetAppletResourceUserId>, "GetAppletResourceUserId"}, | ||
| 17 | {2, D<&IWindowController::GetAppletResourceUserIdOfCallerApplet>, "GetAppletResourceUserIdOfCallerApplet"}, | ||
| 18 | {10, D<&IWindowController::AcquireForegroundRights>, "AcquireForegroundRights"}, | ||
| 19 | {11, D<&IWindowController::ReleaseForegroundRights>, "ReleaseForegroundRights"}, | ||
| 20 | {12, D<&IWindowController::RejectToChangeIntoBackground>, "RejectToChangeIntoBackground"}, | ||
| 21 | {20, D<&IWindowController::SetAppletWindowVisibility>, "SetAppletWindowVisibility"}, | ||
| 22 | {21, D<&IWindowController::SetAppletGpuTimeSlice>, "SetAppletGpuTimeSlice"}, | ||
| 23 | }; | ||
| 24 | // clang-format on | ||
| 25 | |||
| 26 | RegisterHandlers(functions); | ||
| 27 | } | ||
| 28 | |||
| 29 | IWindowController::~IWindowController() = default; | ||
| 30 | |||
| 31 | Result IWindowController::GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid) { | ||
| 32 | LOG_INFO(Service_AM, "called"); | ||
| 33 | *out_aruid = m_applet->aruid; | ||
| 34 | R_SUCCEED(); | ||
| 35 | } | ||
| 36 | |||
| 37 | Result IWindowController::GetAppletResourceUserIdOfCallerApplet( | ||
| 38 | Out<AppletResourceUserId> out_aruid) { | ||
| 39 | LOG_INFO(Service_AM, "called"); | ||
| 40 | |||
| 41 | if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet != nullptr) { | ||
| 42 | *out_aruid = caller_applet->aruid; | ||
| 43 | } else { | ||
| 44 | *out_aruid = AppletResourceUserId{}; | ||
| 45 | } | ||
| 46 | |||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Result IWindowController::AcquireForegroundRights() { | ||
| 51 | LOG_INFO(Service_AM, "called"); | ||
| 52 | R_SUCCEED(); | ||
| 53 | } | ||
| 54 | |||
| 55 | Result IWindowController::ReleaseForegroundRights() { | ||
| 56 | LOG_INFO(Service_AM, "called"); | ||
| 57 | R_SUCCEED(); | ||
| 58 | } | ||
| 59 | |||
| 60 | Result IWindowController::RejectToChangeIntoBackground() { | ||
| 61 | LOG_INFO(Service_AM, "called"); | ||
| 62 | R_SUCCEED(); | ||
| 63 | } | ||
| 64 | |||
| 65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { | ||
| 66 | m_applet->system_buffer_manager.SetWindowVisibility(visible); | ||
| 67 | m_applet->hid_registration.EnableAppletToGetInput(visible); | ||
| 68 | |||
| 69 | if (visible) { | ||
| 70 | m_applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | ||
| 71 | m_applet->focus_state = FocusState::InFocus; | ||
| 72 | } else { | ||
| 73 | m_applet->focus_state = FocusState::NotInFocus; | ||
| 74 | } | ||
| 75 | |||
| 76 | m_applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); | ||
| 77 | |||
| 78 | R_SUCCEED(); | ||
| 79 | } | ||
| 80 | |||
| 81 | Result IWindowController::SetAppletGpuTimeSlice(s64 time_slice) { | ||
| 82 | LOG_WARNING(Service_AM, "(STUBBED) called, time_slice={}", time_slice); | ||
| 83 | R_SUCCEED(); | ||
| 84 | } | ||
| 85 | |||
| 86 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/window_controller.h b/src/core/hle/service/am/service/window_controller.h new file mode 100644 index 000000000..bfbad9bcc --- /dev/null +++ b/src/core/hle/service/am/service/window_controller.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | |||
| 13 | class IWindowController final : public ServiceFramework<IWindowController> { | ||
| 14 | public: | ||
| 15 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet); | ||
| 16 | ~IWindowController() override; | ||
| 17 | |||
| 18 | private: | ||
| 19 | Result GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid); | ||
| 20 | Result GetAppletResourceUserIdOfCallerApplet(Out<AppletResourceUserId> out_aruid); | ||
| 21 | Result AcquireForegroundRights(); | ||
| 22 | Result ReleaseForegroundRights(); | ||
| 23 | Result RejectToChangeIntoBackground(); | ||
| 24 | Result SetAppletWindowVisibility(bool visible); | ||
| 25 | Result SetAppletGpuTimeSlice(s64 time_slice); | ||
| 26 | |||
| 27 | const std::shared_ptr<Applet> m_applet; | ||
| 28 | }; | ||
| 29 | |||
| 30 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h deleted file mode 100644 index 922f8863e..000000000 --- a/src/core/hle/service/am/spsm.h +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::AM { | ||
| 13 | |||
| 14 | class SPSM final : public ServiceFramework<SPSM> { | ||
| 15 | public: | ||
| 16 | explicit SPSM(Core::System& system_); | ||
| 17 | ~SPSM() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/storage.cpp b/src/core/hle/service/am/storage.cpp deleted file mode 100644 index 4e82afd1c..000000000 --- a/src/core/hle/service/am/storage.cpp +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/am_results.h" | ||
| 5 | #include "core/hle/service/am/library_applet_storage.h" | ||
| 6 | #include "core/hle/service/am/storage.h" | ||
| 7 | #include "core/hle/service/am/storage_accessor.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_) | ||
| 13 | : ServiceFramework{system_, "IStorage"}, impl{std::move(impl_)} { | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, &IStorage::Open, "Open"}, | ||
| 16 | {1, &IStorage::OpenTransferStorage, "OpenTransferStorage"}, | ||
| 17 | }; | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IStorage::IStorage(Core::System& system_, std::vector<u8>&& data) | ||
| 23 | : IStorage(system_, CreateStorage(std::move(data))) {} | ||
| 24 | |||
| 25 | IStorage::~IStorage() = default; | ||
| 26 | |||
| 27 | void IStorage::Open(HLERequestContext& ctx) { | ||
| 28 | LOG_DEBUG(Service_AM, "called"); | ||
| 29 | |||
| 30 | if (impl->GetHandle() != nullptr) { | ||
| 31 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 32 | rb.Push(AM::ResultInvalidStorageType); | ||
| 33 | return; | ||
| 34 | } | ||
| 35 | |||
| 36 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 37 | rb.Push(ResultSuccess); | ||
| 38 | rb.PushIpcInterface<IStorageAccessor>(system, impl); | ||
| 39 | } | ||
| 40 | |||
| 41 | void IStorage::OpenTransferStorage(HLERequestContext& ctx) { | ||
| 42 | LOG_DEBUG(Service_AM, "called"); | ||
| 43 | |||
| 44 | if (impl->GetHandle() == nullptr) { | ||
| 45 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 46 | rb.Push(AM::ResultInvalidStorageType); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | |||
| 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 51 | rb.Push(ResultSuccess); | ||
| 52 | rb.PushIpcInterface<ITransferStorageAccessor>(system, impl); | ||
| 53 | } | ||
| 54 | |||
| 55 | std::vector<u8> IStorage::GetData() const { | ||
| 56 | return impl->GetData(); | ||
| 57 | } | ||
| 58 | |||
| 59 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/storage_accessor.cpp b/src/core/hle/service/am/storage_accessor.cpp deleted file mode 100644 index a1184b065..000000000 --- a/src/core/hle/service/am/storage_accessor.cpp +++ /dev/null | |||
| @@ -1,90 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 5 | #include "core/hle/service/am/am_results.h" | ||
| 6 | #include "core/hle/service/am/library_applet_storage.h" | ||
| 7 | #include "core/hle/service/am/storage_accessor.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | |||
| 10 | namespace Service::AM { | ||
| 11 | |||
| 12 | IStorageAccessor::IStorageAccessor(Core::System& system_, | ||
| 13 | std::shared_ptr<LibraryAppletStorage> impl_) | ||
| 14 | : ServiceFramework{system_, "IStorageAccessor"}, impl{std::move(impl_)} { | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, &IStorageAccessor::GetSize, "GetSize"}, | ||
| 17 | {10, &IStorageAccessor::Write, "Write"}, | ||
| 18 | {11, &IStorageAccessor::Read, "Read"}, | ||
| 19 | }; | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | |||
| 24 | IStorageAccessor::~IStorageAccessor() = default; | ||
| 25 | |||
| 26 | void IStorageAccessor::GetSize(HLERequestContext& ctx) { | ||
| 27 | LOG_DEBUG(Service_AM, "called"); | ||
| 28 | |||
| 29 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 30 | |||
| 31 | rb.Push(ResultSuccess); | ||
| 32 | rb.Push(impl->GetSize()); | ||
| 33 | } | ||
| 34 | |||
| 35 | void IStorageAccessor::Write(HLERequestContext& ctx) { | ||
| 36 | IPC::RequestParser rp{ctx}; | ||
| 37 | |||
| 38 | const s64 offset{rp.Pop<s64>()}; | ||
| 39 | const auto data{ctx.ReadBuffer()}; | ||
| 40 | LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size()); | ||
| 41 | |||
| 42 | const auto res{impl->Write(offset, data.data(), data.size())}; | ||
| 43 | |||
| 44 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 45 | rb.Push(res); | ||
| 46 | } | ||
| 47 | |||
| 48 | void IStorageAccessor::Read(HLERequestContext& ctx) { | ||
| 49 | IPC::RequestParser rp{ctx}; | ||
| 50 | |||
| 51 | const s64 offset{rp.Pop<s64>()}; | ||
| 52 | std::vector<u8> data(ctx.GetWriteBufferSize()); | ||
| 53 | |||
| 54 | LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size()); | ||
| 55 | |||
| 56 | const auto res{impl->Read(offset, data.data(), data.size())}; | ||
| 57 | |||
| 58 | ctx.WriteBuffer(data); | ||
| 59 | |||
| 60 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 61 | rb.Push(res); | ||
| 62 | } | ||
| 63 | |||
| 64 | ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_, | ||
| 65 | std::shared_ptr<LibraryAppletStorage> impl_) | ||
| 66 | : ServiceFramework{system_, "ITransferStorageAccessor"}, impl{std::move(impl_)} { | ||
| 67 | static const FunctionInfo functions[] = { | ||
| 68 | {0, &ITransferStorageAccessor::GetSize, "GetSize"}, | ||
| 69 | {1, &ITransferStorageAccessor::GetHandle, "GetHandle"}, | ||
| 70 | }; | ||
| 71 | |||
| 72 | RegisterHandlers(functions); | ||
| 73 | } | ||
| 74 | |||
| 75 | ITransferStorageAccessor::~ITransferStorageAccessor() = default; | ||
| 76 | |||
| 77 | void ITransferStorageAccessor::GetSize(HLERequestContext& ctx) { | ||
| 78 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 79 | rb.Push(ResultSuccess); | ||
| 80 | rb.Push(impl->GetSize()); | ||
| 81 | } | ||
| 82 | |||
| 83 | void ITransferStorageAccessor::GetHandle(HLERequestContext& ctx) { | ||
| 84 | IPC::ResponseBuilder rb{ctx, 4, 1}; | ||
| 85 | rb.Push(ResultSuccess); | ||
| 86 | rb.Push(impl->GetSize()); | ||
| 87 | rb.PushCopyObjects(impl->GetHandle()); | ||
| 88 | } | ||
| 89 | |||
| 90 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/system_applet_proxy.cpp b/src/core/hle/service/am/system_applet_proxy.cpp deleted file mode 100644 index 38643408e..000000000 --- a/src/core/hle/service/am/system_applet_proxy.cpp +++ /dev/null | |||
| @@ -1,136 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet_common_functions.h" | ||
| 5 | #include "core/hle/service/am/application_creator.h" | ||
| 6 | #include "core/hle/service/am/audio_controller.h" | ||
| 7 | #include "core/hle/service/am/common_state_getter.h" | ||
| 8 | #include "core/hle/service/am/debug_functions.h" | ||
| 9 | #include "core/hle/service/am/display_controller.h" | ||
| 10 | #include "core/hle/service/am/global_state_controller.h" | ||
| 11 | #include "core/hle/service/am/home_menu_functions.h" | ||
| 12 | #include "core/hle/service/am/library_applet_creator.h" | ||
| 13 | #include "core/hle/service/am/library_applet_self_accessor.h" | ||
| 14 | #include "core/hle/service/am/process_winding_controller.h" | ||
| 15 | #include "core/hle/service/am/self_controller.h" | ||
| 16 | #include "core/hle/service/am/system_applet_proxy.h" | ||
| 17 | #include "core/hle/service/am/window_controller.h" | ||
| 18 | #include "core/hle/service/ipc_helpers.h" | ||
| 19 | |||
| 20 | namespace Service::AM { | ||
| 21 | |||
| 22 | ISystemAppletProxy::ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 23 | std::shared_ptr<Applet> applet_, Core::System& system_) | ||
| 24 | : ServiceFramework{system_, "ISystemAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move( | ||
| 25 | applet_)} { | ||
| 26 | // clang-format off | ||
| 27 | static const FunctionInfo functions[] = { | ||
| 28 | {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | ||
| 29 | {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"}, | ||
| 30 | {2, &ISystemAppletProxy::GetWindowController, "GetWindowController"}, | ||
| 31 | {3, &ISystemAppletProxy::GetAudioController, "GetAudioController"}, | ||
| 32 | {4, &ISystemAppletProxy::GetDisplayController, "GetDisplayController"}, | ||
| 33 | {10, nullptr, "GetProcessWindingController"}, | ||
| 34 | {11, &ISystemAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, | ||
| 35 | {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, | ||
| 36 | {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, | ||
| 37 | {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, | ||
| 38 | {23, &ISystemAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, | ||
| 39 | {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | |||
| 46 | ISystemAppletProxy::~ISystemAppletProxy() = default; | ||
| 47 | |||
| 48 | void ISystemAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { | ||
| 49 | LOG_DEBUG(Service_AM, "called"); | ||
| 50 | |||
| 51 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); | ||
| 54 | } | ||
| 55 | |||
| 56 | void ISystemAppletProxy::GetSelfController(HLERequestContext& ctx) { | ||
| 57 | LOG_DEBUG(Service_AM, "called"); | ||
| 58 | |||
| 59 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 60 | rb.Push(ResultSuccess); | ||
| 61 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); | ||
| 62 | } | ||
| 63 | |||
| 64 | void ISystemAppletProxy::GetWindowController(HLERequestContext& ctx) { | ||
| 65 | LOG_DEBUG(Service_AM, "called"); | ||
| 66 | |||
| 67 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 68 | rb.Push(ResultSuccess); | ||
| 69 | rb.PushIpcInterface<IWindowController>(system, applet); | ||
| 70 | } | ||
| 71 | |||
| 72 | void ISystemAppletProxy::GetAudioController(HLERequestContext& ctx) { | ||
| 73 | LOG_DEBUG(Service_AM, "called"); | ||
| 74 | |||
| 75 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 76 | rb.Push(ResultSuccess); | ||
| 77 | rb.PushIpcInterface<IAudioController>(system); | ||
| 78 | } | ||
| 79 | |||
| 80 | void ISystemAppletProxy::GetDisplayController(HLERequestContext& ctx) { | ||
| 81 | LOG_DEBUG(Service_AM, "called"); | ||
| 82 | |||
| 83 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 84 | rb.Push(ResultSuccess); | ||
| 85 | rb.PushIpcInterface<IDisplayController>(system, applet); | ||
| 86 | } | ||
| 87 | |||
| 88 | void ISystemAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | ||
| 89 | LOG_DEBUG(Service_AM, "called"); | ||
| 90 | |||
| 91 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 92 | rb.Push(ResultSuccess); | ||
| 93 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); | ||
| 94 | } | ||
| 95 | |||
| 96 | void ISystemAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { | ||
| 97 | LOG_DEBUG(Service_AM, "called"); | ||
| 98 | |||
| 99 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 100 | rb.Push(ResultSuccess); | ||
| 101 | rb.PushIpcInterface<IHomeMenuFunctions>(system); | ||
| 102 | } | ||
| 103 | |||
| 104 | void ISystemAppletProxy::GetGlobalStateController(HLERequestContext& ctx) { | ||
| 105 | LOG_DEBUG(Service_AM, "called"); | ||
| 106 | |||
| 107 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 108 | rb.Push(ResultSuccess); | ||
| 109 | rb.PushIpcInterface<IGlobalStateController>(system); | ||
| 110 | } | ||
| 111 | |||
| 112 | void ISystemAppletProxy::GetApplicationCreator(HLERequestContext& ctx) { | ||
| 113 | LOG_DEBUG(Service_AM, "called"); | ||
| 114 | |||
| 115 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 116 | rb.Push(ResultSuccess); | ||
| 117 | rb.PushIpcInterface<IApplicationCreator>(system); | ||
| 118 | } | ||
| 119 | |||
| 120 | void ISystemAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { | ||
| 121 | LOG_DEBUG(Service_AM, "called"); | ||
| 122 | |||
| 123 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 124 | rb.Push(ResultSuccess); | ||
| 125 | rb.PushIpcInterface<IAppletCommonFunctions>(system, applet); | ||
| 126 | } | ||
| 127 | |||
| 128 | void ISystemAppletProxy::GetDebugFunctions(HLERequestContext& ctx) { | ||
| 129 | LOG_DEBUG(Service_AM, "called"); | ||
| 130 | |||
| 131 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 132 | rb.Push(ResultSuccess); | ||
| 133 | rb.PushIpcInterface<IDebugFunctions>(system); | ||
| 134 | } | ||
| 135 | |||
| 136 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/system_applet_proxy.h b/src/core/hle/service/am/system_applet_proxy.h deleted file mode 100644 index 0390cd1e5..000000000 --- a/src/core/hle/service/am/system_applet_proxy.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | struct Applet; | ||
| 12 | |||
| 13 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | ||
| 14 | public: | ||
| 15 | explicit ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 16 | std::shared_ptr<Applet> applet_, Core::System& system_); | ||
| 17 | ~ISystemAppletProxy(); | ||
| 18 | |||
| 19 | private: | ||
| 20 | void GetCommonStateGetter(HLERequestContext& ctx); | ||
| 21 | void GetSelfController(HLERequestContext& ctx); | ||
| 22 | void GetWindowController(HLERequestContext& ctx); | ||
| 23 | void GetAudioController(HLERequestContext& ctx); | ||
| 24 | void GetDisplayController(HLERequestContext& ctx); | ||
| 25 | void GetLibraryAppletCreator(HLERequestContext& ctx); | ||
| 26 | void GetHomeMenuFunctions(HLERequestContext& ctx); | ||
| 27 | void GetGlobalStateController(HLERequestContext& ctx); | ||
| 28 | void GetApplicationCreator(HLERequestContext& ctx); | ||
| 29 | void GetAppletCommonFunctions(HLERequestContext& ctx); | ||
| 30 | void GetDebugFunctions(HLERequestContext& ctx); | ||
| 31 | |||
| 32 | Nvnflinger::Nvnflinger& nvnflinger; | ||
| 33 | std::shared_ptr<Applet> applet; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/window_controller.cpp b/src/core/hle/service/am/window_controller.cpp deleted file mode 100644 index c07ef228b..000000000 --- a/src/core/hle/service/am/window_controller.cpp +++ /dev/null | |||
| @@ -1,86 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/applet.h" | ||
| 5 | #include "core/hle/service/am/window_controller.h" | ||
| 6 | #include "core/hle/service/ipc_helpers.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 11 | : ServiceFramework{system_, "IWindowController"}, applet{std::move(applet_)} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, nullptr, "CreateWindow"}, | ||
| 15 | {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"}, | ||
| 16 | {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"}, | ||
| 17 | {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"}, | ||
| 18 | {11, nullptr, "ReleaseForegroundRights"}, | ||
| 19 | {12, nullptr, "RejectToChangeIntoBackground"}, | ||
| 20 | {20, &IWindowController::SetAppletWindowVisibility, "SetAppletWindowVisibility"}, | ||
| 21 | {21, &IWindowController::SetAppletGpuTimeSlice, "SetAppletGpuTimeSlice"}, | ||
| 22 | }; | ||
| 23 | // clang-format on | ||
| 24 | |||
| 25 | RegisterHandlers(functions); | ||
| 26 | } | ||
| 27 | |||
| 28 | IWindowController::~IWindowController() = default; | ||
| 29 | |||
| 30 | void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) { | ||
| 31 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 32 | rb.Push(ResultSuccess); | ||
| 33 | rb.Push<u64>(applet->aruid); | ||
| 34 | } | ||
| 35 | |||
| 36 | void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) { | ||
| 37 | u64 aruid = 0; | ||
| 38 | if (auto caller = applet->caller_applet.lock(); caller) { | ||
| 39 | aruid = caller->aruid; | ||
| 40 | } | ||
| 41 | |||
| 42 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 43 | |||
| 44 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 45 | rb.Push(ResultSuccess); | ||
| 46 | rb.Push<u64>(aruid); | ||
| 47 | } | ||
| 48 | |||
| 49 | void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { | ||
| 50 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 51 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | } | ||
| 54 | |||
| 55 | void IWindowController::SetAppletWindowVisibility(HLERequestContext& ctx) { | ||
| 56 | LOG_INFO(Service_AM, "called"); | ||
| 57 | |||
| 58 | IPC::RequestParser rp{ctx}; | ||
| 59 | const bool visible = rp.Pop<bool>(); | ||
| 60 | |||
| 61 | applet->system_buffer_manager.SetWindowVisibility(visible); | ||
| 62 | applet->hid_registration.EnableAppletToGetInput(visible); | ||
| 63 | |||
| 64 | if (visible) { | ||
| 65 | applet->focus_state = FocusState::InFocus; | ||
| 66 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | ||
| 67 | } else { | ||
| 68 | applet->focus_state = FocusState::NotInFocus; | ||
| 69 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground); | ||
| 70 | } | ||
| 71 | |||
| 72 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 73 | rb.Push(ResultSuccess); | ||
| 74 | } | ||
| 75 | |||
| 76 | void IWindowController::SetAppletGpuTimeSlice(HLERequestContext& ctx) { | ||
| 77 | IPC::RequestParser rp{ctx}; | ||
| 78 | const auto time_slice = rp.Pop<s64>(); | ||
| 79 | |||
| 80 | LOG_WARNING(Service_AM, "(STUBBED) called, time_slice={}", time_slice); | ||
| 81 | |||
| 82 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 83 | rb.Push(ResultSuccess); | ||
| 84 | } | ||
| 85 | |||
| 86 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/window_controller.h b/src/core/hle/service/am/window_controller.h deleted file mode 100644 index a28219abe..000000000 --- a/src/core/hle/service/am/window_controller.h +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::AM { | ||
| 9 | |||
| 10 | struct Applet; | ||
| 11 | |||
| 12 | class IWindowController final : public ServiceFramework<IWindowController> { | ||
| 13 | public: | ||
| 14 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
| 15 | ~IWindowController() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | void GetAppletResourceUserId(HLERequestContext& ctx); | ||
| 19 | void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx); | ||
| 20 | void AcquireForegroundRights(HLERequestContext& ctx); | ||
| 21 | void SetAppletWindowVisibility(HLERequestContext& ctx); | ||
| 22 | void SetAppletGpuTimeSlice(HLERequestContext& ctx); | ||
| 23 | |||
| 24 | const std::shared_ptr<Applet> applet; | ||
| 25 | }; | ||
| 26 | |||
| 27 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp index 8f3c04550..b9db19618 100644 --- a/src/core/hle/service/ldn/lan_discovery.cpp +++ b/src/core/hle/service/ldn/lan_discovery.cpp | |||
| @@ -85,15 +85,14 @@ Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network) const { | |||
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network, | 87 | Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network, |
| 88 | std::vector<NodeLatestUpdate>& out_updates, | 88 | std::span<NodeLatestUpdate> out_updates) { |
| 89 | std::size_t buffer_count) { | 89 | if (out_updates.size() > NodeCountMax) { |
| 90 | if (buffer_count > NodeCountMax) { | ||
| 91 | return ResultInvalidBufferCount; | 90 | return ResultInvalidBufferCount; |
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | if (state == State::AccessPointCreated || state == State::StationConnected) { | 93 | if (state == State::AccessPointCreated || state == State::StationConnected) { |
| 95 | std::memcpy(&out_network, &network_info, sizeof(network_info)); | 94 | std::memcpy(&out_network, &network_info, sizeof(network_info)); |
| 96 | for (std::size_t i = 0; i < buffer_count; i++) { | 95 | for (std::size_t i = 0; i < out_updates.size(); i++) { |
| 97 | out_updates[i].state_change = node_changes[i].state_change; | 96 | out_updates[i].state_change = node_changes[i].state_change; |
| 98 | node_changes[i].state_change = NodeStateChange::None; | 97 | node_changes[i].state_change = NodeStateChange::None; |
| 99 | } | 98 | } |
| @@ -107,15 +106,8 @@ DisconnectReason LANDiscovery::GetDisconnectReason() const { | |||
| 107 | return disconnect_reason; | 106 | return disconnect_reason; |
| 108 | } | 107 | } |
| 109 | 108 | ||
| 110 | Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | 109 | Result LANDiscovery::Scan(std::span<NetworkInfo> out_networks, s16& out_count, |
| 111 | const ScanFilter& filter) { | 110 | const ScanFilter& filter) { |
| 112 | if (!IsFlagSet(filter.flag, ScanFilterFlag::NetworkType) || | ||
| 113 | filter.network_type <= NetworkType::All) { | ||
| 114 | if (!IsFlagSet(filter.flag, ScanFilterFlag::Ssid) && filter.ssid.length >= SsidLengthMax) { | ||
| 115 | return ResultBadInput; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | { | 111 | { |
| 120 | std::scoped_lock lock{packet_mutex}; | 112 | std::scoped_lock lock{packet_mutex}; |
| 121 | scan_results.clear(); | 113 | scan_results.clear(); |
| @@ -128,7 +120,7 @@ Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | |||
| 128 | 120 | ||
| 129 | std::scoped_lock lock{packet_mutex}; | 121 | std::scoped_lock lock{packet_mutex}; |
| 130 | for (const auto& [key, info] : scan_results) { | 122 | for (const auto& [key, info] : scan_results) { |
| 131 | if (count >= networks.size()) { | 123 | if (out_count >= static_cast<s16>(out_networks.size())) { |
| 132 | break; | 124 | break; |
| 133 | } | 125 | } |
| 134 | 126 | ||
| @@ -159,7 +151,7 @@ Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | |||
| 159 | } | 151 | } |
| 160 | } | 152 | } |
| 161 | 153 | ||
| 162 | networks[count++] = info; | 154 | out_networks[out_count++] = info; |
| 163 | } | 155 | } |
| 164 | 156 | ||
| 165 | return ResultSuccess; | 157 | return ResultSuccess; |
diff --git a/src/core/hle/service/ldn/lan_discovery.h b/src/core/hle/service/ldn/lan_discovery.h index 3833cd764..8f7a8dfc4 100644 --- a/src/core/hle/service/ldn/lan_discovery.h +++ b/src/core/hle/service/ldn/lan_discovery.h | |||
| @@ -54,11 +54,10 @@ public: | |||
| 54 | void SetState(State new_state); | 54 | void SetState(State new_state); |
| 55 | 55 | ||
| 56 | Result GetNetworkInfo(NetworkInfo& out_network) const; | 56 | Result GetNetworkInfo(NetworkInfo& out_network) const; |
| 57 | Result GetNetworkInfo(NetworkInfo& out_network, std::vector<NodeLatestUpdate>& out_updates, | 57 | Result GetNetworkInfo(NetworkInfo& out_network, std::span<NodeLatestUpdate> out_updates); |
| 58 | std::size_t buffer_count); | ||
| 59 | 58 | ||
| 60 | DisconnectReason GetDisconnectReason() const; | 59 | DisconnectReason GetDisconnectReason() const; |
| 61 | Result Scan(std::vector<NetworkInfo>& networks, u16& count, const ScanFilter& filter); | 60 | Result Scan(std::span<NetworkInfo> out_networks, s16& out_count, const ScanFilter& filter); |
| 62 | Result SetAdvertiseData(std::span<const u8> data); | 61 | Result SetAdvertiseData(std::span<const u8> data); |
| 63 | 62 | ||
| 64 | Result OpenAccessPoint(); | 63 | Result OpenAccessPoint(); |
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index 961f89a14..f2d638c30 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp | |||
| @@ -1,36 +1,24 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <memory> | ||
| 5 | |||
| 6 | #include "core/core.h" | 4 | #include "core/core.h" |
| 7 | #include "core/hle/service/ldn/lan_discovery.h" | 5 | #include "core/hle/service/cmif_serialization.h" |
| 8 | #include "core/hle/service/ldn/ldn.h" | 6 | #include "core/hle/service/ldn/ldn.h" |
| 9 | #include "core/hle/service/ldn/ldn_results.h" | 7 | #include "core/hle/service/ldn/monitor_service.h" |
| 10 | #include "core/hle/service/ldn/ldn_types.h" | 8 | #include "core/hle/service/ldn/sf_monitor_service.h" |
| 11 | #include "core/hle/service/server_manager.h" | 9 | #include "core/hle/service/ldn/sf_service.h" |
| 12 | #include "core/internal_network/network.h" | 10 | #include "core/hle/service/ldn/sf_service_monitor.h" |
| 13 | #include "core/internal_network/network_interface.h" | 11 | #include "core/hle/service/ldn/system_local_communication_service.h" |
| 14 | #include "network/network.h" | 12 | #include "core/hle/service/ldn/user_local_communication_service.h" |
| 15 | |||
| 16 | // This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent | ||
| 17 | #undef CreateEvent | ||
| 18 | 13 | ||
| 19 | namespace Service::LDN { | 14 | namespace Service::LDN { |
| 20 | 15 | ||
| 21 | class IMonitorService final : public ServiceFramework<IMonitorService> { | 16 | class IMonitorServiceCreator final : public ServiceFramework<IMonitorServiceCreator> { |
| 22 | public: | 17 | public: |
| 23 | explicit IMonitorService(Core::System& system_) : ServiceFramework{system_, "IMonitorService"} { | 18 | explicit IMonitorServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:m"} { |
| 24 | // clang-format off | 19 | // clang-format off |
| 25 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 26 | {0, &IMonitorService::GetStateForMonitor, "GetStateForMonitor"}, | 21 | {0, C<&IMonitorServiceCreator::CreateMonitorService>, "CreateMonitorService"} |
| 27 | {1, nullptr, "GetNetworkInfoForMonitor"}, | ||
| 28 | {2, nullptr, "GetIpv4AddressForMonitor"}, | ||
| 29 | {3, nullptr, "GetDisconnectReasonForMonitor"}, | ||
| 30 | {4, nullptr, "GetSecurityParameterForMonitor"}, | ||
| 31 | {5, nullptr, "GetNetworkConfigForMonitor"}, | ||
| 32 | {100, &IMonitorService::InitializeMonitor, "InitializeMonitor"}, | ||
| 33 | {101, nullptr, "FinalizeMonitor"}, | ||
| 34 | }; | 22 | }; |
| 35 | // clang-format on | 23 | // clang-format on |
| 36 | 24 | ||
| @@ -38,84 +26,20 @@ public: | |||
| 38 | } | 26 | } |
| 39 | 27 | ||
| 40 | private: | 28 | private: |
| 41 | void GetStateForMonitor(HLERequestContext& ctx) { | 29 | Result CreateMonitorService(OutInterface<IMonitorService> out_interface) { |
| 42 | LOG_INFO(Service_LDN, "called"); | ||
| 43 | |||
| 44 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 45 | rb.Push(ResultSuccess); | ||
| 46 | rb.PushEnum(state); | ||
| 47 | } | ||
| 48 | |||
| 49 | void InitializeMonitor(HLERequestContext& ctx) { | ||
| 50 | LOG_INFO(Service_LDN, "called"); | ||
| 51 | |||
| 52 | state = State::Initialized; | ||
| 53 | |||
| 54 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 55 | rb.Push(ResultSuccess); | ||
| 56 | } | ||
| 57 | |||
| 58 | State state{State::None}; | ||
| 59 | }; | ||
| 60 | |||
| 61 | class LDNM final : public ServiceFramework<LDNM> { | ||
| 62 | public: | ||
| 63 | explicit LDNM(Core::System& system_) : ServiceFramework{system_, "ldn:m"} { | ||
| 64 | // clang-format off | ||
| 65 | static const FunctionInfo functions[] = { | ||
| 66 | {0, &LDNM::CreateMonitorService, "CreateMonitorService"} | ||
| 67 | }; | ||
| 68 | // clang-format on | ||
| 69 | |||
| 70 | RegisterHandlers(functions); | ||
| 71 | } | ||
| 72 | |||
| 73 | void CreateMonitorService(HLERequestContext& ctx) { | ||
| 74 | LOG_DEBUG(Service_LDN, "called"); | 30 | LOG_DEBUG(Service_LDN, "called"); |
| 75 | 31 | ||
| 76 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 32 | *out_interface = std::make_shared<IMonitorService>(system); |
| 77 | rb.Push(ResultSuccess); | 33 | R_SUCCEED(); |
| 78 | rb.PushIpcInterface<IMonitorService>(system); | ||
| 79 | } | 34 | } |
| 80 | }; | 35 | }; |
| 81 | 36 | ||
| 82 | class ISystemLocalCommunicationService final | 37 | class ISystemServiceCreator final : public ServiceFramework<ISystemServiceCreator> { |
| 83 | : public ServiceFramework<ISystemLocalCommunicationService> { | ||
| 84 | public: | 38 | public: |
| 85 | explicit ISystemLocalCommunicationService(Core::System& system_) | 39 | explicit ISystemServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:s"} { |
| 86 | : ServiceFramework{system_, "ISystemLocalCommunicationService"} { | ||
| 87 | // clang-format off | 40 | // clang-format off |
| 88 | static const FunctionInfo functions[] = { | 41 | static const FunctionInfo functions[] = { |
| 89 | {0, nullptr, "GetState"}, | 42 | {0, C<&ISystemServiceCreator::CreateSystemLocalCommunicationService>, "CreateSystemLocalCommunicationService"}, |
| 90 | {1, nullptr, "GetNetworkInfo"}, | ||
| 91 | {2, nullptr, "GetIpv4Address"}, | ||
| 92 | {3, nullptr, "GetDisconnectReason"}, | ||
| 93 | {4, nullptr, "GetSecurityParameter"}, | ||
| 94 | {5, nullptr, "GetNetworkConfig"}, | ||
| 95 | {100, nullptr, "AttachStateChangeEvent"}, | ||
| 96 | {101, nullptr, "GetNetworkInfoLatestUpdate"}, | ||
| 97 | {102, nullptr, "Scan"}, | ||
| 98 | {103, nullptr, "ScanPrivate"}, | ||
| 99 | {104, nullptr, "SetWirelessControllerRestriction"}, | ||
| 100 | {200, nullptr, "OpenAccessPoint"}, | ||
| 101 | {201, nullptr, "CloseAccessPoint"}, | ||
| 102 | {202, nullptr, "CreateNetwork"}, | ||
| 103 | {203, nullptr, "CreateNetworkPrivate"}, | ||
| 104 | {204, nullptr, "DestroyNetwork"}, | ||
| 105 | {205, nullptr, "Reject"}, | ||
| 106 | {206, nullptr, "SetAdvertiseData"}, | ||
| 107 | {207, nullptr, "SetStationAcceptPolicy"}, | ||
| 108 | {208, nullptr, "AddAcceptFilterEntry"}, | ||
| 109 | {209, nullptr, "ClearAcceptFilter"}, | ||
| 110 | {300, nullptr, "OpenStation"}, | ||
| 111 | {301, nullptr, "CloseStation"}, | ||
| 112 | {302, nullptr, "Connect"}, | ||
| 113 | {303, nullptr, "ConnectPrivate"}, | ||
| 114 | {304, nullptr, "Disconnect"}, | ||
| 115 | {400, nullptr, "InitializeSystem"}, | ||
| 116 | {401, nullptr, "FinalizeSystem"}, | ||
| 117 | {402, nullptr, "SetOperationMode"}, | ||
| 118 | {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"}, | ||
| 119 | }; | 43 | }; |
| 120 | // clang-format on | 44 | // clang-format on |
| 121 | 45 | ||
| @@ -123,687 +47,78 @@ public: | |||
| 123 | } | 47 | } |
| 124 | 48 | ||
| 125 | private: | 49 | private: |
| 126 | void InitializeSystem2(HLERequestContext& ctx) { | 50 | Result CreateSystemLocalCommunicationService( |
| 127 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | 51 | OutInterface<ISystemLocalCommunicationService> out_interface) { |
| 128 | |||
| 129 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 130 | rb.Push(ResultSuccess); | ||
| 131 | } | ||
| 132 | }; | ||
| 133 | |||
| 134 | class IUserLocalCommunicationService final | ||
| 135 | : public ServiceFramework<IUserLocalCommunicationService> { | ||
| 136 | public: | ||
| 137 | explicit IUserLocalCommunicationService(Core::System& system_) | ||
| 138 | : ServiceFramework{system_, "IUserLocalCommunicationService"}, | ||
| 139 | service_context{system, "IUserLocalCommunicationService"}, | ||
| 140 | room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { | ||
| 141 | // clang-format off | ||
| 142 | static const FunctionInfo functions[] = { | ||
| 143 | {0, &IUserLocalCommunicationService::GetState, "GetState"}, | ||
| 144 | {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"}, | ||
| 145 | {2, &IUserLocalCommunicationService::GetIpv4Address, "GetIpv4Address"}, | ||
| 146 | {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"}, | ||
| 147 | {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"}, | ||
| 148 | {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"}, | ||
| 149 | {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"}, | ||
| 150 | {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"}, | ||
| 151 | {102, &IUserLocalCommunicationService::Scan, "Scan"}, | ||
| 152 | {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"}, | ||
| 153 | {104, &IUserLocalCommunicationService::SetWirelessControllerRestriction, "SetWirelessControllerRestriction"}, | ||
| 154 | {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"}, | ||
| 155 | {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"}, | ||
| 156 | {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"}, | ||
| 157 | {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"}, | ||
| 158 | {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"}, | ||
| 159 | {205, nullptr, "Reject"}, | ||
| 160 | {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"}, | ||
| 161 | {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"}, | ||
| 162 | {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"}, | ||
| 163 | {209, nullptr, "ClearAcceptFilter"}, | ||
| 164 | {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"}, | ||
| 165 | {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"}, | ||
| 166 | {302, &IUserLocalCommunicationService::Connect, "Connect"}, | ||
| 167 | {303, nullptr, "ConnectPrivate"}, | ||
| 168 | {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"}, | ||
| 169 | {400, &IUserLocalCommunicationService::Initialize, "Initialize"}, | ||
| 170 | {401, &IUserLocalCommunicationService::Finalize, "Finalize"}, | ||
| 171 | {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, | ||
| 172 | }; | ||
| 173 | // clang-format on | ||
| 174 | |||
| 175 | RegisterHandlers(functions); | ||
| 176 | |||
| 177 | state_change_event = | ||
| 178 | service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); | ||
| 179 | } | ||
| 180 | |||
| 181 | ~IUserLocalCommunicationService() { | ||
| 182 | if (is_initialized) { | ||
| 183 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 184 | room_member->Unbind(ldn_packet_received); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | service_context.CloseEvent(state_change_event); | ||
| 189 | } | ||
| 190 | |||
| 191 | /// Callback to parse and handle a received LDN packet. | ||
| 192 | void OnLDNPacketReceived(const Network::LDNPacket& packet) { | ||
| 193 | lan_discovery.ReceivePacket(packet); | ||
| 194 | } | ||
| 195 | |||
| 196 | void OnEventFired() { | ||
| 197 | state_change_event->Signal(); | ||
| 198 | } | ||
| 199 | |||
| 200 | void GetState(HLERequestContext& ctx) { | ||
| 201 | State state = State::Error; | ||
| 202 | |||
| 203 | if (is_initialized) { | ||
| 204 | state = lan_discovery.GetState(); | ||
| 205 | } | ||
| 206 | |||
| 207 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 208 | rb.Push(ResultSuccess); | ||
| 209 | rb.PushEnum(state); | ||
| 210 | } | ||
| 211 | |||
| 212 | void GetNetworkInfo(HLERequestContext& ctx) { | ||
| 213 | const auto write_buffer_size = ctx.GetWriteBufferSize(); | ||
| 214 | |||
| 215 | if (write_buffer_size != sizeof(NetworkInfo)) { | ||
| 216 | LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); | ||
| 217 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 218 | rb.Push(ResultBadInput); | ||
| 219 | return; | ||
| 220 | } | ||
| 221 | |||
| 222 | NetworkInfo network_info{}; | ||
| 223 | const auto rc = lan_discovery.GetNetworkInfo(network_info); | ||
| 224 | if (rc.IsError()) { | ||
| 225 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
| 226 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 227 | rb.Push(rc); | ||
| 228 | return; | ||
| 229 | } | ||
| 230 | |||
| 231 | ctx.WriteBuffer<NetworkInfo>(network_info); | ||
| 232 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 233 | rb.Push(ResultSuccess); | ||
| 234 | } | ||
| 235 | |||
| 236 | void GetIpv4Address(HLERequestContext& ctx) { | ||
| 237 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
| 238 | |||
| 239 | if (!network_interface) { | ||
| 240 | LOG_ERROR(Service_LDN, "No network interface available"); | ||
| 241 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 242 | rb.Push(ResultNoIpAddress); | ||
| 243 | return; | ||
| 244 | } | ||
| 245 | |||
| 246 | Ipv4Address current_address{Network::TranslateIPv4(network_interface->ip_address)}; | ||
| 247 | Ipv4Address subnet_mask{Network::TranslateIPv4(network_interface->subnet_mask)}; | ||
| 248 | |||
| 249 | // When we're connected to a room, spoof the hosts IP address | ||
| 250 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 251 | if (room_member->IsConnected()) { | ||
| 252 | current_address = room_member->GetFakeIpAddress(); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | std::reverse(std::begin(current_address), std::end(current_address)); // ntohl | ||
| 257 | std::reverse(std::begin(subnet_mask), std::end(subnet_mask)); // ntohl | ||
| 258 | |||
| 259 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 260 | rb.Push(ResultSuccess); | ||
| 261 | rb.PushRaw(current_address); | ||
| 262 | rb.PushRaw(subnet_mask); | ||
| 263 | } | ||
| 264 | |||
| 265 | void GetDisconnectReason(HLERequestContext& ctx) { | ||
| 266 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 267 | rb.Push(ResultSuccess); | ||
| 268 | rb.PushEnum(lan_discovery.GetDisconnectReason()); | ||
| 269 | } | ||
| 270 | |||
| 271 | void GetSecurityParameter(HLERequestContext& ctx) { | ||
| 272 | SecurityParameter security_parameter{}; | ||
| 273 | NetworkInfo info{}; | ||
| 274 | const Result rc = lan_discovery.GetNetworkInfo(info); | ||
| 275 | |||
| 276 | if (rc.IsError()) { | ||
| 277 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
| 278 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 279 | rb.Push(rc); | ||
| 280 | return; | ||
| 281 | } | ||
| 282 | |||
| 283 | security_parameter.session_id = info.network_id.session_id; | ||
| 284 | std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), | ||
| 285 | sizeof(SecurityParameter::data)); | ||
| 286 | |||
| 287 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 288 | rb.Push(rc); | ||
| 289 | rb.PushRaw<SecurityParameter>(security_parameter); | ||
| 290 | } | ||
| 291 | |||
| 292 | void GetNetworkConfig(HLERequestContext& ctx) { | ||
| 293 | NetworkConfig config{}; | ||
| 294 | NetworkInfo info{}; | ||
| 295 | const Result rc = lan_discovery.GetNetworkInfo(info); | ||
| 296 | |||
| 297 | if (rc.IsError()) { | ||
| 298 | LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); | ||
| 299 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 300 | rb.Push(rc); | ||
| 301 | return; | ||
| 302 | } | ||
| 303 | |||
| 304 | config.intent_id = info.network_id.intent_id; | ||
| 305 | config.channel = info.common.channel; | ||
| 306 | config.node_count_max = info.ldn.node_count_max; | ||
| 307 | config.local_communication_version = info.ldn.nodes[0].local_communication_version; | ||
| 308 | |||
| 309 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 310 | rb.Push(rc); | ||
| 311 | rb.PushRaw<NetworkConfig>(config); | ||
| 312 | } | ||
| 313 | |||
| 314 | void AttachStateChangeEvent(HLERequestContext& ctx) { | ||
| 315 | LOG_INFO(Service_LDN, "called"); | ||
| 316 | |||
| 317 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 318 | rb.Push(ResultSuccess); | ||
| 319 | rb.PushCopyObjects(state_change_event->GetReadableEvent()); | ||
| 320 | } | ||
| 321 | |||
| 322 | void GetNetworkInfoLatestUpdate(HLERequestContext& ctx) { | ||
| 323 | const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); | ||
| 324 | const std::size_t node_buffer_count = ctx.GetWriteBufferNumElements<NodeLatestUpdate>(1); | ||
| 325 | |||
| 326 | if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { | ||
| 327 | LOG_ERROR(Service_LDN, "Invalid buffer, size = {}, count = {}", network_buffer_size, | ||
| 328 | node_buffer_count); | ||
| 329 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 330 | rb.Push(ResultBadInput); | ||
| 331 | return; | ||
| 332 | } | ||
| 333 | |||
| 334 | NetworkInfo info{}; | ||
| 335 | std::vector<NodeLatestUpdate> latest_update(node_buffer_count); | ||
| 336 | |||
| 337 | const auto rc = lan_discovery.GetNetworkInfo(info, latest_update, latest_update.size()); | ||
| 338 | if (rc.IsError()) { | ||
| 339 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
| 340 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 341 | rb.Push(rc); | ||
| 342 | return; | ||
| 343 | } | ||
| 344 | |||
| 345 | ctx.WriteBuffer(info, 0); | ||
| 346 | ctx.WriteBuffer(latest_update, 1); | ||
| 347 | |||
| 348 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 349 | rb.Push(ResultSuccess); | ||
| 350 | } | ||
| 351 | |||
| 352 | void Scan(HLERequestContext& ctx) { | ||
| 353 | ScanImpl(ctx); | ||
| 354 | } | ||
| 355 | |||
| 356 | void ScanPrivate(HLERequestContext& ctx) { | ||
| 357 | ScanImpl(ctx, true); | ||
| 358 | } | ||
| 359 | |||
| 360 | void ScanImpl(HLERequestContext& ctx, bool is_private = false) { | ||
| 361 | IPC::RequestParser rp{ctx}; | ||
| 362 | const auto channel{rp.PopEnum<WifiChannel>()}; | ||
| 363 | const auto scan_filter{rp.PopRaw<ScanFilter>()}; | ||
| 364 | |||
| 365 | const std::size_t network_info_size = ctx.GetWriteBufferNumElements<NetworkInfo>(); | ||
| 366 | |||
| 367 | if (network_info_size == 0) { | ||
| 368 | LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); | ||
| 369 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 370 | rb.Push(ResultBadInput); | ||
| 371 | return; | ||
| 372 | } | ||
| 373 | |||
| 374 | u16 count = 0; | ||
| 375 | std::vector<NetworkInfo> network_infos(network_info_size); | ||
| 376 | Result rc = lan_discovery.Scan(network_infos, count, scan_filter); | ||
| 377 | |||
| 378 | LOG_INFO(Service_LDN, | ||
| 379 | "called, channel={}, filter_scan_flag={}, filter_network_type={}, is_private={}", | ||
| 380 | channel, scan_filter.flag, scan_filter.network_type, is_private); | ||
| 381 | |||
| 382 | ctx.WriteBuffer(network_infos); | ||
| 383 | |||
| 384 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 385 | rb.Push(rc); | ||
| 386 | rb.Push<u32>(count); | ||
| 387 | } | ||
| 388 | |||
| 389 | void SetWirelessControllerRestriction(HLERequestContext& ctx) { | ||
| 390 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 391 | |||
| 392 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 393 | rb.Push(ResultSuccess); | ||
| 394 | } | ||
| 395 | |||
| 396 | void OpenAccessPoint(HLERequestContext& ctx) { | ||
| 397 | LOG_INFO(Service_LDN, "called"); | ||
| 398 | |||
| 399 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 400 | rb.Push(lan_discovery.OpenAccessPoint()); | ||
| 401 | } | ||
| 402 | |||
| 403 | void CloseAccessPoint(HLERequestContext& ctx) { | ||
| 404 | LOG_INFO(Service_LDN, "called"); | ||
| 405 | |||
| 406 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 407 | rb.Push(lan_discovery.CloseAccessPoint()); | ||
| 408 | } | ||
| 409 | |||
| 410 | void CreateNetwork(HLERequestContext& ctx) { | ||
| 411 | LOG_INFO(Service_LDN, "called"); | ||
| 412 | |||
| 413 | CreateNetworkImpl(ctx); | ||
| 414 | } | ||
| 415 | |||
| 416 | void CreateNetworkPrivate(HLERequestContext& ctx) { | ||
| 417 | LOG_INFO(Service_LDN, "called"); | ||
| 418 | |||
| 419 | CreateNetworkImpl(ctx, true); | ||
| 420 | } | ||
| 421 | |||
| 422 | void CreateNetworkImpl(HLERequestContext& ctx, bool is_private = false) { | ||
| 423 | IPC::RequestParser rp{ctx}; | ||
| 424 | |||
| 425 | const auto security_config{rp.PopRaw<SecurityConfig>()}; | ||
| 426 | [[maybe_unused]] const auto security_parameter{is_private ? rp.PopRaw<SecurityParameter>() | ||
| 427 | : SecurityParameter{}}; | ||
| 428 | const auto user_config{rp.PopRaw<UserConfig>()}; | ||
| 429 | rp.Pop<u32>(); // Padding | ||
| 430 | const auto network_Config{rp.PopRaw<NetworkConfig>()}; | ||
| 431 | |||
| 432 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 433 | rb.Push(lan_discovery.CreateNetwork(security_config, user_config, network_Config)); | ||
| 434 | } | ||
| 435 | |||
| 436 | void DestroyNetwork(HLERequestContext& ctx) { | ||
| 437 | LOG_INFO(Service_LDN, "called"); | ||
| 438 | |||
| 439 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 440 | rb.Push(lan_discovery.DestroyNetwork()); | ||
| 441 | } | ||
| 442 | |||
| 443 | void SetAdvertiseData(HLERequestContext& ctx) { | ||
| 444 | const auto read_buffer = ctx.ReadBuffer(); | ||
| 445 | |||
| 446 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 447 | rb.Push(lan_discovery.SetAdvertiseData(read_buffer)); | ||
| 448 | } | ||
| 449 | |||
| 450 | void SetStationAcceptPolicy(HLERequestContext& ctx) { | ||
| 451 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 452 | |||
| 453 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 454 | rb.Push(ResultSuccess); | ||
| 455 | } | ||
| 456 | |||
| 457 | void AddAcceptFilterEntry(HLERequestContext& ctx) { | ||
| 458 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 459 | |||
| 460 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 461 | rb.Push(ResultSuccess); | ||
| 462 | } | ||
| 463 | |||
| 464 | void OpenStation(HLERequestContext& ctx) { | ||
| 465 | LOG_INFO(Service_LDN, "called"); | ||
| 466 | |||
| 467 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 468 | rb.Push(lan_discovery.OpenStation()); | ||
| 469 | } | ||
| 470 | |||
| 471 | void CloseStation(HLERequestContext& ctx) { | ||
| 472 | LOG_INFO(Service_LDN, "called"); | ||
| 473 | |||
| 474 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 475 | rb.Push(lan_discovery.CloseStation()); | ||
| 476 | } | ||
| 477 | |||
| 478 | void Connect(HLERequestContext& ctx) { | ||
| 479 | IPC::RequestParser rp{ctx}; | ||
| 480 | struct Parameters { | ||
| 481 | SecurityConfig security_config; | ||
| 482 | UserConfig user_config; | ||
| 483 | u32 local_communication_version; | ||
| 484 | u32 option; | ||
| 485 | }; | ||
| 486 | static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); | ||
| 487 | |||
| 488 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 489 | |||
| 490 | LOG_INFO(Service_LDN, | ||
| 491 | "called, passphrase_size={}, security_mode={}, " | ||
| 492 | "local_communication_version={}", | ||
| 493 | parameters.security_config.passphrase_size, | ||
| 494 | parameters.security_config.security_mode, parameters.local_communication_version); | ||
| 495 | |||
| 496 | const auto read_buffer = ctx.ReadBuffer(); | ||
| 497 | if (read_buffer.size() != sizeof(NetworkInfo)) { | ||
| 498 | LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); | ||
| 499 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 500 | rb.Push(ResultBadInput); | ||
| 501 | return; | ||
| 502 | } | ||
| 503 | |||
| 504 | NetworkInfo network_info{}; | ||
| 505 | std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); | ||
| 506 | |||
| 507 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 508 | rb.Push(lan_discovery.Connect(network_info, parameters.user_config, | ||
| 509 | static_cast<u16>(parameters.local_communication_version))); | ||
| 510 | } | ||
| 511 | |||
| 512 | void Disconnect(HLERequestContext& ctx) { | ||
| 513 | LOG_INFO(Service_LDN, "called"); | ||
| 514 | |||
| 515 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 516 | rb.Push(lan_discovery.Disconnect()); | ||
| 517 | } | ||
| 518 | |||
| 519 | void Initialize(HLERequestContext& ctx) { | ||
| 520 | const auto rc = InitializeImpl(ctx); | ||
| 521 | if (rc.IsError()) { | ||
| 522 | LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); | ||
| 523 | } | ||
| 524 | |||
| 525 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 526 | rb.Push(rc); | ||
| 527 | } | ||
| 528 | |||
| 529 | void Finalize(HLERequestContext& ctx) { | ||
| 530 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 531 | room_member->Unbind(ldn_packet_received); | ||
| 532 | } | ||
| 533 | |||
| 534 | is_initialized = false; | ||
| 535 | |||
| 536 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 537 | rb.Push(lan_discovery.Finalize()); | ||
| 538 | } | ||
| 539 | |||
| 540 | void Initialize2(HLERequestContext& ctx) { | ||
| 541 | const auto rc = InitializeImpl(ctx); | ||
| 542 | if (rc.IsError()) { | ||
| 543 | LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); | ||
| 544 | } | ||
| 545 | |||
| 546 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 547 | rb.Push(rc); | ||
| 548 | } | ||
| 549 | |||
| 550 | Result InitializeImpl(HLERequestContext& ctx) { | ||
| 551 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
| 552 | if (!network_interface) { | ||
| 553 | LOG_ERROR(Service_LDN, "No network interface is set"); | ||
| 554 | return ResultAirplaneModeEnabled; | ||
| 555 | } | ||
| 556 | |||
| 557 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 558 | ldn_packet_received = room_member->BindOnLdnPacketReceived( | ||
| 559 | [this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); }); | ||
| 560 | } else { | ||
| 561 | LOG_ERROR(Service_LDN, "Couldn't bind callback!"); | ||
| 562 | return ResultAirplaneModeEnabled; | ||
| 563 | } | ||
| 564 | |||
| 565 | lan_discovery.Initialize([&]() { OnEventFired(); }); | ||
| 566 | is_initialized = true; | ||
| 567 | return ResultSuccess; | ||
| 568 | } | ||
| 569 | |||
| 570 | KernelHelpers::ServiceContext service_context; | ||
| 571 | Kernel::KEvent* state_change_event; | ||
| 572 | Network::RoomNetwork& room_network; | ||
| 573 | LANDiscovery lan_discovery; | ||
| 574 | |||
| 575 | // Callback identifier for the OnLDNPacketReceived event. | ||
| 576 | Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received; | ||
| 577 | |||
| 578 | bool is_initialized{}; | ||
| 579 | }; | ||
| 580 | |||
| 581 | class LDNS final : public ServiceFramework<LDNS> { | ||
| 582 | public: | ||
| 583 | explicit LDNS(Core::System& system_) : ServiceFramework{system_, "ldn:s"} { | ||
| 584 | // clang-format off | ||
| 585 | static const FunctionInfo functions[] = { | ||
| 586 | {0, &LDNS::CreateSystemLocalCommunicationService, "CreateSystemLocalCommunicationService"}, | ||
| 587 | }; | ||
| 588 | // clang-format on | ||
| 589 | |||
| 590 | RegisterHandlers(functions); | ||
| 591 | } | ||
| 592 | |||
| 593 | void CreateSystemLocalCommunicationService(HLERequestContext& ctx) { | ||
| 594 | LOG_DEBUG(Service_LDN, "called"); | 52 | LOG_DEBUG(Service_LDN, "called"); |
| 595 | 53 | ||
| 596 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 54 | *out_interface = std::make_shared<ISystemLocalCommunicationService>(system); |
| 597 | rb.Push(ResultSuccess); | 55 | R_SUCCEED(); |
| 598 | rb.PushIpcInterface<ISystemLocalCommunicationService>(system); | ||
| 599 | } | 56 | } |
| 600 | }; | 57 | }; |
| 601 | 58 | ||
| 602 | class LDNU final : public ServiceFramework<LDNU> { | 59 | class IUserServiceCreator final : public ServiceFramework<IUserServiceCreator> { |
| 603 | public: | 60 | public: |
| 604 | explicit LDNU(Core::System& system_) : ServiceFramework{system_, "ldn:u"} { | 61 | explicit IUserServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:u"} { |
| 605 | // clang-format off | 62 | // clang-format off |
| 606 | static const FunctionInfo functions[] = { | 63 | static const FunctionInfo functions[] = { |
| 607 | {0, &LDNU::CreateUserLocalCommunicationService, "CreateUserLocalCommunicationService"}, | 64 | {0, C<&IUserServiceCreator::CreateUserLocalCommunicationService>, "CreateUserLocalCommunicationService"}, |
| 608 | }; | 65 | }; |
| 609 | // clang-format on | 66 | // clang-format on |
| 610 | 67 | ||
| 611 | RegisterHandlers(functions); | 68 | RegisterHandlers(functions); |
| 612 | } | 69 | } |
| 613 | 70 | ||
| 614 | void CreateUserLocalCommunicationService(HLERequestContext& ctx) { | 71 | private: |
| 72 | Result CreateUserLocalCommunicationService( | ||
| 73 | OutInterface<IUserLocalCommunicationService> out_interface) { | ||
| 615 | LOG_DEBUG(Service_LDN, "called"); | 74 | LOG_DEBUG(Service_LDN, "called"); |
| 616 | 75 | ||
| 617 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 76 | *out_interface = std::make_shared<IUserLocalCommunicationService>(system); |
| 618 | rb.Push(ResultSuccess); | 77 | R_SUCCEED(); |
| 619 | rb.PushIpcInterface<IUserLocalCommunicationService>(system); | ||
| 620 | } | 78 | } |
| 621 | }; | 79 | }; |
| 622 | 80 | ||
| 623 | class INetworkService final : public ServiceFramework<INetworkService> { | 81 | class ISfServiceCreator final : public ServiceFramework<ISfServiceCreator> { |
| 624 | public: | 82 | public: |
| 625 | explicit INetworkService(Core::System& system_) : ServiceFramework{system_, "INetworkService"} { | 83 | explicit ISfServiceCreator(Core::System& system_, bool is_system_, const char* name_) |
| 84 | : ServiceFramework{system_, name_}, is_system{is_system_} { | ||
| 626 | // clang-format off | 85 | // clang-format off |
| 627 | static const FunctionInfo functions[] = { | 86 | static const FunctionInfo functions[] = { |
| 628 | {0, nullptr, "Initialize"}, | 87 | {0, C<&ISfServiceCreator::CreateNetworkService>, "CreateNetworkService"}, |
| 629 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | 88 | {8, C<&ISfServiceCreator::CreateNetworkServiceMonitor>, "CreateNetworkServiceMonitor"}, |
| 630 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
| 631 | {272, nullptr, "GetRole"}, | ||
| 632 | {280, nullptr, "GetAdvertiseData"}, | ||
| 633 | {288, nullptr, "GetGroupInfo"}, | ||
| 634 | {296, nullptr, "GetGroupInfo2"}, | ||
| 635 | {304, nullptr, "GetGroupOwner"}, | ||
| 636 | {312, nullptr, "GetIpConfig"}, | ||
| 637 | {320, nullptr, "GetLinkLevel"}, | ||
| 638 | {512, nullptr, "Scan"}, | ||
| 639 | {768, nullptr, "CreateGroup"}, | ||
| 640 | {776, nullptr, "DestroyGroup"}, | ||
| 641 | {784, nullptr, "SetAdvertiseData"}, | ||
| 642 | {1536, nullptr, "SendToOtherGroup"}, | ||
| 643 | {1544, nullptr, "RecvFromOtherGroup"}, | ||
| 644 | {1552, nullptr, "AddAcceptableGroupId"}, | ||
| 645 | {1560, nullptr, "ClearAcceptableGroupId"}, | ||
| 646 | }; | 89 | }; |
| 647 | // clang-format on | 90 | // clang-format on |
| 648 | 91 | ||
| 649 | RegisterHandlers(functions); | 92 | RegisterHandlers(functions); |
| 650 | } | 93 | } |
| 651 | }; | ||
| 652 | |||
| 653 | class INetworkServiceMonitor final : public ServiceFramework<INetworkServiceMonitor> { | ||
| 654 | public: | ||
| 655 | explicit INetworkServiceMonitor(Core::System& system_) | ||
| 656 | : ServiceFramework{system_, "INetworkServiceMonitor"} { | ||
| 657 | // clang-format off | ||
| 658 | static const FunctionInfo functions[] = { | ||
| 659 | {0, &INetworkServiceMonitor::Initialize, "Initialize"}, | ||
| 660 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
| 661 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
| 662 | {272, nullptr, "GetRole"}, | ||
| 663 | {280, nullptr, "GetAdvertiseData"}, | ||
| 664 | {281, nullptr, "GetAdvertiseData2"}, | ||
| 665 | {288, nullptr, "GetGroupInfo"}, | ||
| 666 | {296, nullptr, "GetGroupInfo2"}, | ||
| 667 | {304, nullptr, "GetGroupOwner"}, | ||
| 668 | {312, nullptr, "GetIpConfig"}, | ||
| 669 | {320, nullptr, "GetLinkLevel"}, | ||
| 670 | {328, nullptr, "AttachJoinEvent"}, | ||
| 671 | {336, nullptr, "GetMembers"}, | ||
| 672 | }; | ||
| 673 | // clang-format on | ||
| 674 | |||
| 675 | RegisterHandlers(functions); | ||
| 676 | } | ||
| 677 | |||
| 678 | void Initialize(HLERequestContext& ctx) { | ||
| 679 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 680 | |||
| 681 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 682 | rb.Push(ResultDisabled); | ||
| 683 | } | ||
| 684 | }; | ||
| 685 | |||
| 686 | class LP2PAPP final : public ServiceFramework<LP2PAPP> { | ||
| 687 | public: | ||
| 688 | explicit LP2PAPP(Core::System& system_) : ServiceFramework{system_, "lp2p:app"} { | ||
| 689 | // clang-format off | ||
| 690 | static const FunctionInfo functions[] = { | ||
| 691 | {0, &LP2PAPP::CreateMonitorService, "CreateNetworkService"}, | ||
| 692 | {8, &LP2PAPP::CreateMonitorService, "CreateNetworkServiceMonitor"}, | ||
| 693 | }; | ||
| 694 | // clang-format on | ||
| 695 | |||
| 696 | RegisterHandlers(functions); | ||
| 697 | } | ||
| 698 | |||
| 699 | void CreateNetworkervice(HLERequestContext& ctx) { | ||
| 700 | IPC::RequestParser rp{ctx}; | ||
| 701 | const u64 reserved_input = rp.Pop<u64>(); | ||
| 702 | const u32 input = rp.Pop<u32>(); | ||
| 703 | |||
| 704 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, | ||
| 705 | input); | ||
| 706 | |||
| 707 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 708 | rb.Push(ResultSuccess); | ||
| 709 | rb.PushIpcInterface<INetworkService>(system); | ||
| 710 | } | ||
| 711 | |||
| 712 | void CreateMonitorService(HLERequestContext& ctx) { | ||
| 713 | IPC::RequestParser rp{ctx}; | ||
| 714 | const u64 reserved_input = rp.Pop<u64>(); | ||
| 715 | |||
| 716 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); | ||
| 717 | |||
| 718 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 719 | rb.Push(ResultSuccess); | ||
| 720 | rb.PushIpcInterface<INetworkServiceMonitor>(system); | ||
| 721 | } | ||
| 722 | }; | ||
| 723 | |||
| 724 | class LP2PSYS final : public ServiceFramework<LP2PSYS> { | ||
| 725 | public: | ||
| 726 | explicit LP2PSYS(Core::System& system_) : ServiceFramework{system_, "lp2p:sys"} { | ||
| 727 | // clang-format off | ||
| 728 | static const FunctionInfo functions[] = { | ||
| 729 | {0, &LP2PSYS::CreateMonitorService, "CreateNetworkService"}, | ||
| 730 | {8, &LP2PSYS::CreateMonitorService, "CreateNetworkServiceMonitor"}, | ||
| 731 | }; | ||
| 732 | // clang-format on | ||
| 733 | |||
| 734 | RegisterHandlers(functions); | ||
| 735 | } | ||
| 736 | |||
| 737 | void CreateNetworkervice(HLERequestContext& ctx) { | ||
| 738 | IPC::RequestParser rp{ctx}; | ||
| 739 | const u64 reserved_input = rp.Pop<u64>(); | ||
| 740 | const u32 input = rp.Pop<u32>(); | ||
| 741 | 94 | ||
| 95 | private: | ||
| 96 | Result CreateNetworkService(OutInterface<ISfService> out_interface, u32 input, | ||
| 97 | u64 reserved_input) { | ||
| 742 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, | 98 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, |
| 743 | input); | 99 | input); |
| 744 | 100 | ||
| 745 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 101 | *out_interface = std::make_shared<ISfService>(system); |
| 746 | rb.Push(ResultSuccess); | 102 | R_SUCCEED(); |
| 747 | rb.PushIpcInterface<INetworkService>(system); | ||
| 748 | } | 103 | } |
| 749 | 104 | ||
| 750 | void CreateMonitorService(HLERequestContext& ctx) { | 105 | Result CreateNetworkServiceMonitor(OutInterface<ISfServiceMonitor> out_interface, |
| 751 | IPC::RequestParser rp{ctx}; | 106 | u64 reserved_input) { |
| 752 | const u64 reserved_input = rp.Pop<u64>(); | ||
| 753 | |||
| 754 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); | 107 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); |
| 755 | 108 | ||
| 756 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 109 | *out_interface = std::make_shared<ISfServiceMonitor>(system); |
| 757 | rb.Push(ResultSuccess); | 110 | R_SUCCEED(); |
| 758 | rb.PushIpcInterface<INetworkServiceMonitor>(system); | ||
| 759 | } | 111 | } |
| 760 | }; | ||
| 761 | 112 | ||
| 762 | class ISfMonitorService final : public ServiceFramework<ISfMonitorService> { | 113 | bool is_system{}; |
| 763 | public: | ||
| 764 | explicit ISfMonitorService(Core::System& system_) | ||
| 765 | : ServiceFramework{system_, "ISfMonitorService"} { | ||
| 766 | // clang-format off | ||
| 767 | static const FunctionInfo functions[] = { | ||
| 768 | {0, &ISfMonitorService::Initialize, "Initialize"}, | ||
| 769 | {288, &ISfMonitorService::GetGroupInfo, "GetGroupInfo"}, | ||
| 770 | {320, nullptr, "GetLinkLevel"}, | ||
| 771 | }; | ||
| 772 | // clang-format on | ||
| 773 | |||
| 774 | RegisterHandlers(functions); | ||
| 775 | } | ||
| 776 | |||
| 777 | private: | ||
| 778 | void Initialize(HLERequestContext& ctx) { | ||
| 779 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 780 | |||
| 781 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 782 | rb.Push(ResultSuccess); | ||
| 783 | rb.Push(0); | ||
| 784 | } | ||
| 785 | |||
| 786 | void GetGroupInfo(HLERequestContext& ctx) { | ||
| 787 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 788 | |||
| 789 | struct GroupInfo { | ||
| 790 | std::array<u8, 0x200> info; | ||
| 791 | }; | ||
| 792 | |||
| 793 | GroupInfo group_info{}; | ||
| 794 | |||
| 795 | ctx.WriteBuffer(group_info); | ||
| 796 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 797 | rb.Push(ResultSuccess); | ||
| 798 | } | ||
| 799 | }; | 114 | }; |
| 800 | 115 | ||
| 801 | class LP2PM final : public ServiceFramework<LP2PM> { | 116 | class ISfMonitorServiceCreator final : public ServiceFramework<ISfMonitorServiceCreator> { |
| 802 | public: | 117 | public: |
| 803 | explicit LP2PM(Core::System& system_) : ServiceFramework{system_, "lp2p:m"} { | 118 | explicit ISfMonitorServiceCreator(Core::System& system_) : ServiceFramework{system_, "lp2p:m"} { |
| 804 | // clang-format off | 119 | // clang-format off |
| 805 | static const FunctionInfo functions[] = { | 120 | static const FunctionInfo functions[] = { |
| 806 | {0, &LP2PM::CreateMonitorService, "CreateMonitorService"}, | 121 | {0, C<&ISfMonitorServiceCreator::CreateMonitorService>, "CreateMonitorService"}, |
| 807 | }; | 122 | }; |
| 808 | // clang-format on | 123 | // clang-format on |
| 809 | 124 | ||
| @@ -811,28 +126,27 @@ public: | |||
| 811 | } | 126 | } |
| 812 | 127 | ||
| 813 | private: | 128 | private: |
| 814 | void CreateMonitorService(HLERequestContext& ctx) { | 129 | Result CreateMonitorService(OutInterface<ISfMonitorService> out_interface, u64 reserved_input) { |
| 815 | IPC::RequestParser rp{ctx}; | ||
| 816 | const u64 reserved_input = rp.Pop<u64>(); | ||
| 817 | |||
| 818 | LOG_INFO(Service_LDN, "called, reserved_input={}", reserved_input); | 130 | LOG_INFO(Service_LDN, "called, reserved_input={}", reserved_input); |
| 819 | 131 | ||
| 820 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 132 | *out_interface = std::make_shared<ISfMonitorService>(system); |
| 821 | rb.Push(ResultSuccess); | 133 | R_SUCCEED(); |
| 822 | rb.PushIpcInterface<ISfMonitorService>(system); | ||
| 823 | } | 134 | } |
| 824 | }; | 135 | }; |
| 825 | 136 | ||
| 826 | void LoopProcess(Core::System& system) { | 137 | void LoopProcess(Core::System& system) { |
| 827 | auto server_manager = std::make_unique<ServerManager>(system); | 138 | auto server_manager = std::make_unique<ServerManager>(system); |
| 828 | 139 | ||
| 829 | server_manager->RegisterNamedService("ldn:m", std::make_shared<LDNM>(system)); | 140 | server_manager->RegisterNamedService("ldn:m", std::make_shared<IMonitorServiceCreator>(system)); |
| 830 | server_manager->RegisterNamedService("ldn:s", std::make_shared<LDNS>(system)); | 141 | server_manager->RegisterNamedService("ldn:s", std::make_shared<ISystemServiceCreator>(system)); |
| 831 | server_manager->RegisterNamedService("ldn:u", std::make_shared<LDNU>(system)); | 142 | server_manager->RegisterNamedService("ldn:u", std::make_shared<IUserServiceCreator>(system)); |
| 832 | 143 | ||
| 833 | server_manager->RegisterNamedService("lp2p:app", std::make_shared<LP2PAPP>(system)); | 144 | server_manager->RegisterNamedService( |
| 834 | server_manager->RegisterNamedService("lp2p:sys", std::make_shared<LP2PSYS>(system)); | 145 | "lp2p:app", std::make_shared<ISfServiceCreator>(system, false, "lp2p:app")); |
| 835 | server_manager->RegisterNamedService("lp2p:m", std::make_shared<LP2PM>(system)); | 146 | server_manager->RegisterNamedService( |
| 147 | "lp2p:sys", std::make_shared<ISfServiceCreator>(system, true, "lp2p:sys")); | ||
| 148 | server_manager->RegisterNamedService("lp2p:m", | ||
| 149 | std::make_shared<ISfMonitorServiceCreator>(system)); | ||
| 836 | 150 | ||
| 837 | ServerManager::RunServer(std::move(server_manager)); | 151 | ServerManager::RunServer(std::move(server_manager)); |
| 838 | } | 152 | } |
diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index f4a319168..dae037fa8 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h | |||
| @@ -3,12 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/kernel/k_event.h" | ||
| 7 | #include "core/hle/result.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | #include "core/hle/service/kernel_helpers.h" | ||
| 10 | #include "core/hle/service/sm/sm.h" | ||
| 11 | |||
| 12 | namespace Core { | 6 | namespace Core { |
| 13 | class System; | 7 | class System; |
| 14 | } | 8 | } |
diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h index 44c2c773b..6198aa07b 100644 --- a/src/core/hle/service/ldn/ldn_types.h +++ b/src/core/hle/service/ldn/ldn_types.h | |||
| @@ -123,6 +123,18 @@ enum class NodeStatus : u8 { | |||
| 123 | Connected, | 123 | Connected, |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | enum class WirelessControllerRestriction : u32 { | ||
| 127 | None, | ||
| 128 | Default, | ||
| 129 | }; | ||
| 130 | |||
| 131 | struct ConnectOption { | ||
| 132 | union { | ||
| 133 | u32 raw; | ||
| 134 | }; | ||
| 135 | }; | ||
| 136 | static_assert(sizeof(ConnectOption) == 0x4, "ConnectOption is an invalid size"); | ||
| 137 | |||
| 126 | struct NodeLatestUpdate { | 138 | struct NodeLatestUpdate { |
| 127 | NodeStateChange state_change; | 139 | NodeStateChange state_change; |
| 128 | INSERT_PADDING_BYTES(0x7); // Unknown | 140 | INSERT_PADDING_BYTES(0x7); // Unknown |
| @@ -139,9 +151,9 @@ static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size"); | |||
| 139 | 151 | ||
| 140 | struct IntentId { | 152 | struct IntentId { |
| 141 | u64 local_communication_id; | 153 | u64 local_communication_id; |
| 142 | INSERT_PADDING_BYTES(0x2); // Reserved | 154 | INSERT_PADDING_BYTES_NOINIT(0x2); // Reserved |
| 143 | u16 scene_id; | 155 | u16 scene_id; |
| 144 | INSERT_PADDING_BYTES(0x4); // Reserved | 156 | INSERT_PADDING_BYTES_NOINIT(0x4); // Reserved |
| 145 | }; | 157 | }; |
| 146 | static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); | 158 | static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); |
| 147 | 159 | ||
| @@ -152,13 +164,14 @@ struct NetworkId { | |||
| 152 | static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); | 164 | static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); |
| 153 | 165 | ||
| 154 | struct Ssid { | 166 | struct Ssid { |
| 155 | u8 length{}; | 167 | u8 length; |
| 156 | std::array<char, SsidLengthMax + 1> raw{}; | 168 | std::array<char, SsidLengthMax + 1> raw; |
| 157 | 169 | ||
| 158 | Ssid() = default; | 170 | Ssid() = default; |
| 159 | 171 | ||
| 160 | constexpr explicit Ssid(std::string_view data) { | 172 | constexpr explicit Ssid(std::string_view data) { |
| 161 | length = static_cast<u8>(std::min(data.size(), SsidLengthMax)); | 173 | length = static_cast<u8>(std::min(data.size(), SsidLengthMax)); |
| 174 | raw = {}; | ||
| 162 | data.copy(raw.data(), length); | 175 | data.copy(raw.data(), length); |
| 163 | raw[length] = 0; | 176 | raw[length] = 0; |
| 164 | } | 177 | } |
| @@ -181,7 +194,7 @@ using Ipv4Address = std::array<u8, 4>; | |||
| 181 | static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); | 194 | static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); |
| 182 | 195 | ||
| 183 | struct MacAddress { | 196 | struct MacAddress { |
| 184 | std::array<u8, 6> raw{}; | 197 | std::array<u8, 6> raw; |
| 185 | 198 | ||
| 186 | friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; | 199 | friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; |
| 187 | }; | 200 | }; |
| @@ -211,7 +224,7 @@ struct CommonNetworkInfo { | |||
| 211 | WifiChannel channel; | 224 | WifiChannel channel; |
| 212 | LinkLevel link_level; | 225 | LinkLevel link_level; |
| 213 | PackedNetworkType network_type; | 226 | PackedNetworkType network_type; |
| 214 | INSERT_PADDING_BYTES(0x4); | 227 | INSERT_PADDING_BYTES_NOINIT(0x4); |
| 215 | }; | 228 | }; |
| 216 | static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); | 229 | static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); |
| 217 | 230 | ||
| @@ -221,9 +234,9 @@ struct NodeInfo { | |||
| 221 | s8 node_id; | 234 | s8 node_id; |
| 222 | u8 is_connected; | 235 | u8 is_connected; |
| 223 | std::array<u8, UserNameBytesMax + 1> user_name; | 236 | std::array<u8, UserNameBytesMax + 1> user_name; |
| 224 | INSERT_PADDING_BYTES(0x1); // Reserved | 237 | INSERT_PADDING_BYTES_NOINIT(0x1); // Reserved |
| 225 | s16 local_communication_version; | 238 | s16 local_communication_version; |
| 226 | INSERT_PADDING_BYTES(0x10); // Reserved | 239 | INSERT_PADDING_BYTES_NOINIT(0x10); // Reserved |
| 227 | }; | 240 | }; |
| 228 | static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); | 241 | static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); |
| 229 | 242 | ||
| @@ -232,14 +245,14 @@ struct LdnNetworkInfo { | |||
| 232 | SecurityMode security_mode; | 245 | SecurityMode security_mode; |
| 233 | AcceptPolicy station_accept_policy; | 246 | AcceptPolicy station_accept_policy; |
| 234 | u8 has_action_frame; | 247 | u8 has_action_frame; |
| 235 | INSERT_PADDING_BYTES(0x2); // Padding | 248 | INSERT_PADDING_BYTES_NOINIT(0x2); // Padding |
| 236 | u8 node_count_max; | 249 | u8 node_count_max; |
| 237 | u8 node_count; | 250 | u8 node_count; |
| 238 | std::array<NodeInfo, NodeCountMax> nodes; | 251 | std::array<NodeInfo, NodeCountMax> nodes; |
| 239 | INSERT_PADDING_BYTES(0x2); // Reserved | 252 | INSERT_PADDING_BYTES_NOINIT(0x2); // Reserved |
| 240 | u16 advertise_data_size; | 253 | u16 advertise_data_size; |
| 241 | std::array<u8, AdvertiseDataSizeMax> advertise_data; | 254 | std::array<u8, AdvertiseDataSizeMax> advertise_data; |
| 242 | INSERT_PADDING_BYTES(0x8C); // Reserved | 255 | INSERT_PADDING_BYTES_NOINIT(0x8C); // Reserved |
| 243 | u64 random_authentication_id; | 256 | u64 random_authentication_id; |
| 244 | }; | 257 | }; |
| 245 | static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); | 258 | static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); |
| @@ -250,6 +263,7 @@ struct NetworkInfo { | |||
| 250 | LdnNetworkInfo ldn; | 263 | LdnNetworkInfo ldn; |
| 251 | }; | 264 | }; |
| 252 | static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); | 265 | static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); |
| 266 | static_assert(std::is_trivial_v<NetworkInfo>, "NetworkInfo type must be trivially copyable."); | ||
| 253 | 267 | ||
| 254 | struct SecurityConfig { | 268 | struct SecurityConfig { |
| 255 | SecurityMode security_mode; | 269 | SecurityMode security_mode; |
| @@ -303,4 +317,36 @@ struct AddressList { | |||
| 303 | }; | 317 | }; |
| 304 | static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); | 318 | static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); |
| 305 | 319 | ||
| 320 | struct GroupInfo { | ||
| 321 | std::array<u8, 0x200> info; | ||
| 322 | }; | ||
| 323 | |||
| 324 | struct CreateNetworkConfig { | ||
| 325 | SecurityConfig security_config; | ||
| 326 | UserConfig user_config; | ||
| 327 | INSERT_PADDING_BYTES(0x4); | ||
| 328 | NetworkConfig network_config; | ||
| 329 | }; | ||
| 330 | static_assert(sizeof(CreateNetworkConfig) == 0x98, "CreateNetworkConfig is an invalid size"); | ||
| 331 | |||
| 332 | #pragma pack(push, 4) | ||
| 333 | struct CreateNetworkConfigPrivate { | ||
| 334 | SecurityConfig security_config; | ||
| 335 | SecurityParameter security_parameter; | ||
| 336 | UserConfig user_config; | ||
| 337 | INSERT_PADDING_BYTES(0x4); | ||
| 338 | NetworkConfig network_config; | ||
| 339 | }; | ||
| 340 | #pragma pack(pop) | ||
| 341 | static_assert(sizeof(CreateNetworkConfigPrivate) == 0xB8, | ||
| 342 | "CreateNetworkConfigPrivate is an invalid size"); | ||
| 343 | |||
| 344 | struct ConnectNetworkData { | ||
| 345 | SecurityConfig security_config; | ||
| 346 | UserConfig user_config; | ||
| 347 | s32 local_communication_version; | ||
| 348 | ConnectOption option; | ||
| 349 | }; | ||
| 350 | static_assert(sizeof(ConnectNetworkData) == 0x7c, "ConnectNetworkData is an invalid size"); | ||
| 351 | |||
| 306 | } // namespace Service::LDN | 352 | } // namespace Service::LDN |
diff --git a/src/core/hle/service/ldn/monitor_service.cpp b/src/core/hle/service/ldn/monitor_service.cpp new file mode 100644 index 000000000..3471f69da --- /dev/null +++ b/src/core/hle/service/ldn/monitor_service.cpp | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ldn/monitor_service.h" | ||
| 6 | |||
| 7 | namespace Service::LDN { | ||
| 8 | |||
| 9 | IMonitorService::IMonitorService(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IMonitorService"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, C<&IMonitorService::GetStateForMonitor>, "GetStateForMonitor"}, | ||
| 14 | {1, nullptr, "GetNetworkInfoForMonitor"}, | ||
| 15 | {2, nullptr, "GetIpv4AddressForMonitor"}, | ||
| 16 | {3, nullptr, "GetDisconnectReasonForMonitor"}, | ||
| 17 | {4, nullptr, "GetSecurityParameterForMonitor"}, | ||
| 18 | {5, nullptr, "GetNetworkConfigForMonitor"}, | ||
| 19 | {100, C<&IMonitorService::InitializeMonitor>, "InitializeMonitor"}, | ||
| 20 | {101, nullptr, "FinalizeMonitor"}, | ||
| 21 | }; | ||
| 22 | // clang-format on | ||
| 23 | |||
| 24 | RegisterHandlers(functions); | ||
| 25 | } | ||
| 26 | |||
| 27 | IMonitorService::~IMonitorService() = default; | ||
| 28 | |||
| 29 | Result IMonitorService::GetStateForMonitor(Out<State> out_state) { | ||
| 30 | LOG_INFO(Service_LDN, "called"); | ||
| 31 | |||
| 32 | *out_state = state; | ||
| 33 | R_SUCCEED(); | ||
| 34 | } | ||
| 35 | |||
| 36 | Result IMonitorService::InitializeMonitor() { | ||
| 37 | LOG_INFO(Service_LDN, "called"); | ||
| 38 | |||
| 39 | state = State::Initialized; | ||
| 40 | R_SUCCEED(); | ||
| 41 | } | ||
| 42 | |||
| 43 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/monitor_service.h b/src/core/hle/service/ldn/monitor_service.h new file mode 100644 index 000000000..61aacef30 --- /dev/null +++ b/src/core/hle/service/ldn/monitor_service.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ldn/ldn_types.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Core { | ||
| 11 | class System; | ||
| 12 | } | ||
| 13 | |||
| 14 | namespace Service::LDN { | ||
| 15 | |||
| 16 | class IMonitorService final : public ServiceFramework<IMonitorService> { | ||
| 17 | public: | ||
| 18 | explicit IMonitorService(Core::System& system_); | ||
| 19 | ~IMonitorService() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result GetStateForMonitor(Out<State> out_state); | ||
| 23 | Result InitializeMonitor(); | ||
| 24 | |||
| 25 | State state{State::None}; | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_monitor_service.cpp b/src/core/hle/service/ldn/sf_monitor_service.cpp new file mode 100644 index 000000000..9e6736ff2 --- /dev/null +++ b/src/core/hle/service/ldn/sf_monitor_service.cpp | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ldn/ldn_types.h" | ||
| 6 | #include "core/hle/service/ldn/sf_monitor_service.h" | ||
| 7 | |||
| 8 | namespace Service::LDN { | ||
| 9 | |||
| 10 | ISfMonitorService::ISfMonitorService(Core::System& system_) | ||
| 11 | : ServiceFramework{system_, "ISfMonitorService"} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, C<&ISfMonitorService::Initialize>, "Initialize"}, | ||
| 15 | {288, C<&ISfMonitorService::GetGroupInfo>, "GetGroupInfo"}, | ||
| 16 | {320, nullptr, "GetLinkLevel"}, | ||
| 17 | }; | ||
| 18 | // clang-format on | ||
| 19 | |||
| 20 | RegisterHandlers(functions); | ||
| 21 | } | ||
| 22 | |||
| 23 | ISfMonitorService::~ISfMonitorService() = default; | ||
| 24 | |||
| 25 | Result ISfMonitorService::Initialize(Out<u32> out_value) { | ||
| 26 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 27 | |||
| 28 | *out_value = 0; | ||
| 29 | R_SUCCEED(); | ||
| 30 | } | ||
| 31 | |||
| 32 | Result ISfMonitorService::GetGroupInfo( | ||
| 33 | OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info) { | ||
| 34 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 35 | |||
| 36 | *out_group_info = GroupInfo{}; | ||
| 37 | R_SUCCEED(); | ||
| 38 | } | ||
| 39 | |||
| 40 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_monitor_service.h b/src/core/hle/service/ldn/sf_monitor_service.h new file mode 100644 index 000000000..d02115201 --- /dev/null +++ b/src/core/hle/service/ldn/sf_monitor_service.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::LDN { | ||
| 14 | struct GroupInfo; | ||
| 15 | |||
| 16 | class ISfMonitorService final : public ServiceFramework<ISfMonitorService> { | ||
| 17 | public: | ||
| 18 | explicit ISfMonitorService(Core::System& system_); | ||
| 19 | ~ISfMonitorService() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result Initialize(Out<u32> out_value); | ||
| 23 | Result GetGroupInfo(OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info); | ||
| 24 | }; | ||
| 25 | |||
| 26 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service.cpp b/src/core/hle/service/ldn/sf_service.cpp new file mode 100644 index 000000000..61cabe219 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service.cpp | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ldn/sf_service.h" | ||
| 5 | |||
| 6 | namespace Service::LDN { | ||
| 7 | |||
| 8 | ISfService::ISfService(Core::System& system_) : ServiceFramework{system_, "ISfService"} { | ||
| 9 | // clang-format off | ||
| 10 | static const FunctionInfo functions[] = { | ||
| 11 | {0, nullptr, "Initialize"}, | ||
| 12 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
| 13 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
| 14 | {272, nullptr, "GetRole"}, | ||
| 15 | {280, nullptr, "GetAdvertiseData"}, | ||
| 16 | {288, nullptr, "GetGroupInfo"}, | ||
| 17 | {296, nullptr, "GetGroupInfo2"}, | ||
| 18 | {304, nullptr, "GetGroupOwner"}, | ||
| 19 | {312, nullptr, "GetIpConfig"}, | ||
| 20 | {320, nullptr, "GetLinkLevel"}, | ||
| 21 | {512, nullptr, "Scan"}, | ||
| 22 | {768, nullptr, "CreateGroup"}, | ||
| 23 | {776, nullptr, "DestroyGroup"}, | ||
| 24 | {784, nullptr, "SetAdvertiseData"}, | ||
| 25 | {1536, nullptr, "SendToOtherGroup"}, | ||
| 26 | {1544, nullptr, "RecvFromOtherGroup"}, | ||
| 27 | {1552, nullptr, "AddAcceptableGroupId"}, | ||
| 28 | {1560, nullptr, "ClearAcceptableGroupId"}, | ||
| 29 | }; | ||
| 30 | // clang-format on | ||
| 31 | |||
| 32 | RegisterHandlers(functions); | ||
| 33 | } | ||
| 34 | |||
| 35 | ISfService::~ISfService() = default; | ||
| 36 | |||
| 37 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service.h b/src/core/hle/service/ldn/sf_service.h new file mode 100644 index 000000000..05534b567 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::LDN { | ||
| 14 | |||
| 15 | class ISfService final : public ServiceFramework<ISfService> { | ||
| 16 | public: | ||
| 17 | explicit ISfService(Core::System& system_); | ||
| 18 | ~ISfService() override; | ||
| 19 | }; | ||
| 20 | |||
| 21 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service_monitor.cpp b/src/core/hle/service/ldn/sf_service_monitor.cpp new file mode 100644 index 000000000..33e3c1d69 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service_monitor.cpp | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ldn/ldn_types.h" | ||
| 6 | #include "core/hle/service/ldn/sf_service_monitor.h" | ||
| 7 | |||
| 8 | namespace Service::LDN { | ||
| 9 | |||
| 10 | ISfServiceMonitor::ISfServiceMonitor(Core::System& system_) | ||
| 11 | : ServiceFramework{system_, "ISfServiceMonitor"} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, C<&ISfServiceMonitor::Initialize>, "Initialize"}, | ||
| 15 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
| 16 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
| 17 | {272, nullptr, "GetRole"}, | ||
| 18 | {280, nullptr, "GetAdvertiseData"}, | ||
| 19 | {281, nullptr, "GetAdvertiseData2"}, | ||
| 20 | {288, C<&ISfServiceMonitor::GetGroupInfo>, "GetGroupInfo"}, | ||
| 21 | {296, nullptr, "GetGroupInfo2"}, | ||
| 22 | {304, nullptr, "GetGroupOwner"}, | ||
| 23 | {312, nullptr, "GetIpConfig"}, | ||
| 24 | {320, nullptr, "GetLinkLevel"}, | ||
| 25 | {328, nullptr, "AttachJoinEvent"}, | ||
| 26 | {336, nullptr, "GetMembers"}, | ||
| 27 | }; | ||
| 28 | // clang-format on | ||
| 29 | |||
| 30 | RegisterHandlers(functions); | ||
| 31 | } | ||
| 32 | |||
| 33 | ISfServiceMonitor::~ISfServiceMonitor() = default; | ||
| 34 | |||
| 35 | Result ISfServiceMonitor::Initialize(Out<u32> out_value) { | ||
| 36 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 37 | |||
| 38 | *out_value = 0; | ||
| 39 | R_SUCCEED(); | ||
| 40 | } | ||
| 41 | |||
| 42 | Result ISfServiceMonitor::GetGroupInfo( | ||
| 43 | OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info) { | ||
| 44 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 45 | |||
| 46 | *out_group_info = GroupInfo{}; | ||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service_monitor.h b/src/core/hle/service/ldn/sf_service_monitor.h new file mode 100644 index 000000000..3cfc5005e --- /dev/null +++ b/src/core/hle/service/ldn/sf_service_monitor.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::LDN { | ||
| 14 | struct GroupInfo; | ||
| 15 | |||
| 16 | class ISfServiceMonitor final : public ServiceFramework<ISfServiceMonitor> { | ||
| 17 | public: | ||
| 18 | explicit ISfServiceMonitor(Core::System& system_); | ||
| 19 | ~ISfServiceMonitor() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result Initialize(Out<u32> out_value); | ||
| 23 | Result GetGroupInfo(OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info); | ||
| 24 | }; | ||
| 25 | |||
| 26 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/system_local_communication_service.cpp b/src/core/hle/service/ldn/system_local_communication_service.cpp new file mode 100644 index 000000000..7b52223cd --- /dev/null +++ b/src/core/hle/service/ldn/system_local_communication_service.cpp | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ldn/system_local_communication_service.h" | ||
| 6 | |||
| 7 | namespace Service::LDN { | ||
| 8 | |||
| 9 | ISystemLocalCommunicationService::ISystemLocalCommunicationService(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ISystemLocalCommunicationService"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "GetState"}, | ||
| 14 | {1, nullptr, "GetNetworkInfo"}, | ||
| 15 | {2, nullptr, "GetIpv4Address"}, | ||
| 16 | {3, nullptr, "GetDisconnectReason"}, | ||
| 17 | {4, nullptr, "GetSecurityParameter"}, | ||
| 18 | {5, nullptr, "GetNetworkConfig"}, | ||
| 19 | {100, nullptr, "AttachStateChangeEvent"}, | ||
| 20 | {101, nullptr, "GetNetworkInfoLatestUpdate"}, | ||
| 21 | {102, nullptr, "Scan"}, | ||
| 22 | {103, nullptr, "ScanPrivate"}, | ||
| 23 | {104, nullptr, "SetWirelessControllerRestriction"}, | ||
| 24 | {200, nullptr, "OpenAccessPoint"}, | ||
| 25 | {201, nullptr, "CloseAccessPoint"}, | ||
| 26 | {202, nullptr, "CreateNetwork"}, | ||
| 27 | {203, nullptr, "CreateNetworkPrivate"}, | ||
| 28 | {204, nullptr, "DestroyNetwork"}, | ||
| 29 | {205, nullptr, "Reject"}, | ||
| 30 | {206, nullptr, "SetAdvertiseData"}, | ||
| 31 | {207, nullptr, "SetStationAcceptPolicy"}, | ||
| 32 | {208, nullptr, "AddAcceptFilterEntry"}, | ||
| 33 | {209, nullptr, "ClearAcceptFilter"}, | ||
| 34 | {300, nullptr, "OpenStation"}, | ||
| 35 | {301, nullptr, "CloseStation"}, | ||
| 36 | {302, nullptr, "Connect"}, | ||
| 37 | {303, nullptr, "ConnectPrivate"}, | ||
| 38 | {304, nullptr, "Disconnect"}, | ||
| 39 | {400, nullptr, "InitializeSystem"}, | ||
| 40 | {401, nullptr, "FinalizeSystem"}, | ||
| 41 | {402, nullptr, "SetOperationMode"}, | ||
| 42 | {403, C<&ISystemLocalCommunicationService::InitializeSystem2>, "InitializeSystem2"}, | ||
| 43 | }; | ||
| 44 | // clang-format on | ||
| 45 | |||
| 46 | RegisterHandlers(functions); | ||
| 47 | } | ||
| 48 | |||
| 49 | ISystemLocalCommunicationService::~ISystemLocalCommunicationService() = default; | ||
| 50 | |||
| 51 | Result ISystemLocalCommunicationService::InitializeSystem2() { | ||
| 52 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 53 | R_SUCCEED(); | ||
| 54 | } | ||
| 55 | |||
| 56 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/system_local_communication_service.h b/src/core/hle/service/ldn/system_local_communication_service.h new file mode 100644 index 000000000..a02b097ea --- /dev/null +++ b/src/core/hle/service/ldn/system_local_communication_service.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::LDN { | ||
| 14 | |||
| 15 | class ISystemLocalCommunicationService final | ||
| 16 | : public ServiceFramework<ISystemLocalCommunicationService> { | ||
| 17 | public: | ||
| 18 | explicit ISystemLocalCommunicationService(Core::System& system_); | ||
| 19 | ~ISystemLocalCommunicationService() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result InitializeSystem2(); | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp new file mode 100644 index 000000000..f28368962 --- /dev/null +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp | |||
| @@ -0,0 +1,320 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include <memory> | ||
| 5 | |||
| 6 | #include "core/core.h" | ||
| 7 | #include "core/hle/kernel/k_event.h" | ||
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 9 | #include "core/hle/service/ldn/ldn_results.h" | ||
| 10 | #include "core/hle/service/ldn/ldn_types.h" | ||
| 11 | #include "core/hle/service/ldn/user_local_communication_service.h" | ||
| 12 | #include "core/hle/service/server_manager.h" | ||
| 13 | #include "core/internal_network/network.h" | ||
| 14 | #include "core/internal_network/network_interface.h" | ||
| 15 | #include "network/network.h" | ||
| 16 | |||
| 17 | // This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent | ||
| 18 | #undef CreateEvent | ||
| 19 | |||
| 20 | namespace Service::LDN { | ||
| 21 | |||
| 22 | IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_) | ||
| 23 | : ServiceFramework{system_, "IUserLocalCommunicationService"}, | ||
| 24 | service_context{system, "IUserLocalCommunicationService"}, | ||
| 25 | room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { | ||
| 26 | // clang-format off | ||
| 27 | static const FunctionInfo functions[] = { | ||
| 28 | {0, C<&IUserLocalCommunicationService::GetState>, "GetState"}, | ||
| 29 | {1, C<&IUserLocalCommunicationService::GetNetworkInfo>, "GetNetworkInfo"}, | ||
| 30 | {2, C<&IUserLocalCommunicationService::GetIpv4Address>, "GetIpv4Address"}, | ||
| 31 | {3, C<&IUserLocalCommunicationService::GetDisconnectReason>, "GetDisconnectReason"}, | ||
| 32 | {4, C<&IUserLocalCommunicationService::GetSecurityParameter>, "GetSecurityParameter"}, | ||
| 33 | {5, C<&IUserLocalCommunicationService::GetNetworkConfig>, "GetNetworkConfig"}, | ||
| 34 | {100, C<&IUserLocalCommunicationService::AttachStateChangeEvent>, "AttachStateChangeEvent"}, | ||
| 35 | {101, C<&IUserLocalCommunicationService::GetNetworkInfoLatestUpdate>, "GetNetworkInfoLatestUpdate"}, | ||
| 36 | {102, C<&IUserLocalCommunicationService::Scan>, "Scan"}, | ||
| 37 | {103, C<&IUserLocalCommunicationService::ScanPrivate>, "ScanPrivate"}, | ||
| 38 | {104, C<&IUserLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"}, | ||
| 39 | {200, C<&IUserLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"}, | ||
| 40 | {201, C<&IUserLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"}, | ||
| 41 | {202, C<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"}, | ||
| 42 | {203, C<&IUserLocalCommunicationService::CreateNetworkPrivate>, "CreateNetworkPrivate"}, | ||
| 43 | {204, C<&IUserLocalCommunicationService::DestroyNetwork>, "DestroyNetwork"}, | ||
| 44 | {205, nullptr, "Reject"}, | ||
| 45 | {206, C<&IUserLocalCommunicationService::SetAdvertiseData>, "SetAdvertiseData"}, | ||
| 46 | {207, C<&IUserLocalCommunicationService::SetStationAcceptPolicy>, "SetStationAcceptPolicy"}, | ||
| 47 | {208, C<&IUserLocalCommunicationService::AddAcceptFilterEntry>, "AddAcceptFilterEntry"}, | ||
| 48 | {209, nullptr, "ClearAcceptFilter"}, | ||
| 49 | {300, C<&IUserLocalCommunicationService::OpenStation>, "OpenStation"}, | ||
| 50 | {301, C<&IUserLocalCommunicationService::CloseStation>, "CloseStation"}, | ||
| 51 | {302, C<&IUserLocalCommunicationService::Connect>, "Connect"}, | ||
| 52 | {303, nullptr, "ConnectPrivate"}, | ||
| 53 | {304, C<&IUserLocalCommunicationService::Disconnect>, "Disconnect"}, | ||
| 54 | {400, C<&IUserLocalCommunicationService::Initialize>, "Initialize"}, | ||
| 55 | {401, C<&IUserLocalCommunicationService::Finalize>, "Finalize"}, | ||
| 56 | {402, C<&IUserLocalCommunicationService::Initialize2>, "Initialize2"}, | ||
| 57 | }; | ||
| 58 | // clang-format on | ||
| 59 | |||
| 60 | RegisterHandlers(functions); | ||
| 61 | |||
| 62 | state_change_event = | ||
| 63 | service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); | ||
| 64 | } | ||
| 65 | |||
| 66 | IUserLocalCommunicationService::~IUserLocalCommunicationService() { | ||
| 67 | if (is_initialized) { | ||
| 68 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 69 | room_member->Unbind(ldn_packet_received); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | service_context.CloseEvent(state_change_event); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result IUserLocalCommunicationService::GetState(Out<State> out_state) { | ||
| 77 | *out_state = State::Error; | ||
| 78 | |||
| 79 | if (is_initialized) { | ||
| 80 | *out_state = lan_discovery.GetState(); | ||
| 81 | } | ||
| 82 | |||
| 83 | LOG_INFO(Service_LDN, "called, state={}", *out_state); | ||
| 84 | |||
| 85 | R_SUCCEED(); | ||
| 86 | } | ||
| 87 | |||
| 88 | Result IUserLocalCommunicationService::GetNetworkInfo( | ||
| 89 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info) { | ||
| 90 | LOG_INFO(Service_LDN, "called"); | ||
| 91 | |||
| 92 | R_RETURN(lan_discovery.GetNetworkInfo(*out_network_info)); | ||
| 93 | } | ||
| 94 | |||
| 95 | Result IUserLocalCommunicationService::GetIpv4Address(Out<Ipv4Address> out_current_address, | ||
| 96 | Out<Ipv4Address> out_subnet_mask) { | ||
| 97 | LOG_INFO(Service_LDN, "called"); | ||
| 98 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
| 99 | |||
| 100 | R_UNLESS(network_interface.has_value(), ResultNoIpAddress); | ||
| 101 | |||
| 102 | *out_current_address = {Network::TranslateIPv4(network_interface->ip_address)}; | ||
| 103 | *out_subnet_mask = {Network::TranslateIPv4(network_interface->subnet_mask)}; | ||
| 104 | |||
| 105 | // When we're connected to a room, spoof the hosts IP address | ||
| 106 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 107 | if (room_member->IsConnected()) { | ||
| 108 | *out_current_address = room_member->GetFakeIpAddress(); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | std::reverse(std::begin(*out_current_address), std::end(*out_current_address)); // ntohl | ||
| 113 | std::reverse(std::begin(*out_subnet_mask), std::end(*out_subnet_mask)); // ntohl | ||
| 114 | R_SUCCEED(); | ||
| 115 | } | ||
| 116 | |||
| 117 | Result IUserLocalCommunicationService::GetDisconnectReason( | ||
| 118 | Out<DisconnectReason> out_disconnect_reason) { | ||
| 119 | LOG_INFO(Service_LDN, "called"); | ||
| 120 | |||
| 121 | *out_disconnect_reason = lan_discovery.GetDisconnectReason(); | ||
| 122 | R_SUCCEED(); | ||
| 123 | } | ||
| 124 | |||
| 125 | Result IUserLocalCommunicationService::GetSecurityParameter( | ||
| 126 | Out<SecurityParameter> out_security_parameter) { | ||
| 127 | LOG_INFO(Service_LDN, "called"); | ||
| 128 | |||
| 129 | NetworkInfo info{}; | ||
| 130 | R_TRY(lan_discovery.GetNetworkInfo(info)); | ||
| 131 | |||
| 132 | out_security_parameter->session_id = info.network_id.session_id; | ||
| 133 | std::memcpy(out_security_parameter->data.data(), info.ldn.security_parameter.data(), | ||
| 134 | sizeof(SecurityParameter::data)); | ||
| 135 | R_SUCCEED(); | ||
| 136 | } | ||
| 137 | |||
| 138 | Result IUserLocalCommunicationService::GetNetworkConfig(Out<NetworkConfig> out_network_config) { | ||
| 139 | LOG_INFO(Service_LDN, "called"); | ||
| 140 | |||
| 141 | NetworkInfo info{}; | ||
| 142 | R_TRY(lan_discovery.GetNetworkInfo(info)); | ||
| 143 | |||
| 144 | out_network_config->intent_id = info.network_id.intent_id; | ||
| 145 | out_network_config->channel = info.common.channel; | ||
| 146 | out_network_config->node_count_max = info.ldn.node_count_max; | ||
| 147 | out_network_config->local_communication_version = info.ldn.nodes[0].local_communication_version; | ||
| 148 | R_SUCCEED(); | ||
| 149 | } | ||
| 150 | |||
| 151 | Result IUserLocalCommunicationService::AttachStateChangeEvent( | ||
| 152 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 153 | LOG_INFO(Service_LDN, "called"); | ||
| 154 | |||
| 155 | *out_event = &state_change_event->GetReadableEvent(); | ||
| 156 | R_SUCCEED(); | ||
| 157 | } | ||
| 158 | |||
| 159 | Result IUserLocalCommunicationService::GetNetworkInfoLatestUpdate( | ||
| 160 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info, | ||
| 161 | OutArray<NodeLatestUpdate, BufferAttr_HipcPointer> out_node_latest_update) { | ||
| 162 | LOG_INFO(Service_LDN, "called"); | ||
| 163 | |||
| 164 | R_UNLESS(!out_node_latest_update.empty(), ResultBadInput); | ||
| 165 | |||
| 166 | R_RETURN(lan_discovery.GetNetworkInfo(*out_network_info, out_node_latest_update)); | ||
| 167 | } | ||
| 168 | |||
| 169 | Result IUserLocalCommunicationService::Scan( | ||
| 170 | Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
| 171 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info) { | ||
| 172 | LOG_INFO(Service_LDN, "called, channel={}, filter_scan_flag={}, filter_network_type={}", | ||
| 173 | channel, scan_filter.flag, scan_filter.network_type); | ||
| 174 | |||
| 175 | R_UNLESS(!out_network_info.empty(), ResultBadInput); | ||
| 176 | R_RETURN(lan_discovery.Scan(out_network_info, *network_count, scan_filter)); | ||
| 177 | } | ||
| 178 | |||
| 179 | Result IUserLocalCommunicationService::ScanPrivate( | ||
| 180 | Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
| 181 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info) { | ||
| 182 | LOG_INFO(Service_LDN, "called, channel={}, filter_scan_flag={}, filter_network_type={}", | ||
| 183 | channel, scan_filter.flag, scan_filter.network_type); | ||
| 184 | |||
| 185 | R_UNLESS(out_network_info.empty(), ResultBadInput); | ||
| 186 | R_RETURN(lan_discovery.Scan(out_network_info, *network_count, scan_filter)); | ||
| 187 | } | ||
| 188 | |||
| 189 | Result IUserLocalCommunicationService::SetWirelessControllerRestriction( | ||
| 190 | WirelessControllerRestriction wireless_restriction) { | ||
| 191 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 192 | R_SUCCEED(); | ||
| 193 | } | ||
| 194 | |||
| 195 | Result IUserLocalCommunicationService::OpenAccessPoint() { | ||
| 196 | LOG_INFO(Service_LDN, "called"); | ||
| 197 | |||
| 198 | R_RETURN(lan_discovery.OpenAccessPoint()); | ||
| 199 | } | ||
| 200 | |||
| 201 | Result IUserLocalCommunicationService::CloseAccessPoint() { | ||
| 202 | LOG_INFO(Service_LDN, "called"); | ||
| 203 | |||
| 204 | R_RETURN(lan_discovery.CloseAccessPoint()); | ||
| 205 | } | ||
| 206 | |||
| 207 | Result IUserLocalCommunicationService::CreateNetwork(const CreateNetworkConfig& create_config) { | ||
| 208 | LOG_INFO(Service_LDN, "called"); | ||
| 209 | |||
| 210 | R_RETURN(lan_discovery.CreateNetwork(create_config.security_config, create_config.user_config, | ||
| 211 | create_config.network_config)); | ||
| 212 | } | ||
| 213 | |||
| 214 | Result IUserLocalCommunicationService::CreateNetworkPrivate( | ||
| 215 | const CreateNetworkConfigPrivate& create_config, | ||
| 216 | InArray<AddressEntry, BufferAttr_HipcPointer> address_list) { | ||
| 217 | LOG_INFO(Service_LDN, "called"); | ||
| 218 | |||
| 219 | R_RETURN(lan_discovery.CreateNetwork(create_config.security_config, create_config.user_config, | ||
| 220 | create_config.network_config)); | ||
| 221 | } | ||
| 222 | |||
| 223 | Result IUserLocalCommunicationService::DestroyNetwork() { | ||
| 224 | LOG_INFO(Service_LDN, "called"); | ||
| 225 | |||
| 226 | R_RETURN(lan_discovery.DestroyNetwork()); | ||
| 227 | } | ||
| 228 | |||
| 229 | Result IUserLocalCommunicationService::SetAdvertiseData( | ||
| 230 | InBuffer<BufferAttr_HipcAutoSelect> buffer_data) { | ||
| 231 | LOG_INFO(Service_LDN, "called"); | ||
| 232 | |||
| 233 | R_RETURN(lan_discovery.SetAdvertiseData(buffer_data)); | ||
| 234 | } | ||
| 235 | |||
| 236 | Result IUserLocalCommunicationService::SetStationAcceptPolicy(AcceptPolicy accept_policy) { | ||
| 237 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 238 | R_SUCCEED(); | ||
| 239 | } | ||
| 240 | |||
| 241 | Result IUserLocalCommunicationService::AddAcceptFilterEntry(MacAddress mac_address) { | ||
| 242 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
| 243 | R_SUCCEED(); | ||
| 244 | } | ||
| 245 | |||
| 246 | Result IUserLocalCommunicationService::OpenStation() { | ||
| 247 | LOG_INFO(Service_LDN, "called"); | ||
| 248 | |||
| 249 | R_RETURN(lan_discovery.OpenStation()); | ||
| 250 | } | ||
| 251 | |||
| 252 | Result IUserLocalCommunicationService::CloseStation() { | ||
| 253 | LOG_INFO(Service_LDN, "called"); | ||
| 254 | |||
| 255 | R_RETURN(lan_discovery.CloseStation()); | ||
| 256 | } | ||
| 257 | |||
| 258 | Result IUserLocalCommunicationService::Connect( | ||
| 259 | const ConnectNetworkData& connect_data, | ||
| 260 | InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info) { | ||
| 261 | LOG_INFO(Service_LDN, | ||
| 262 | "called, passphrase_size={}, security_mode={}, " | ||
| 263 | "local_communication_version={}", | ||
| 264 | connect_data.security_config.passphrase_size, | ||
| 265 | connect_data.security_config.security_mode, connect_data.local_communication_version); | ||
| 266 | |||
| 267 | R_RETURN(lan_discovery.Connect(*network_info, connect_data.user_config, | ||
| 268 | static_cast<u16>(connect_data.local_communication_version))); | ||
| 269 | } | ||
| 270 | |||
| 271 | Result IUserLocalCommunicationService::Disconnect() { | ||
| 272 | LOG_INFO(Service_LDN, "called"); | ||
| 273 | |||
| 274 | R_RETURN(lan_discovery.Disconnect()); | ||
| 275 | } | ||
| 276 | |||
| 277 | Result IUserLocalCommunicationService::Initialize(ClientProcessId aruid) { | ||
| 278 | LOG_INFO(Service_LDN, "called, process_id={}", aruid.pid); | ||
| 279 | |||
| 280 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
| 281 | R_UNLESS(network_interface, ResultAirplaneModeEnabled); | ||
| 282 | |||
| 283 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 284 | ldn_packet_received = room_member->BindOnLdnPacketReceived( | ||
| 285 | [this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); }); | ||
| 286 | } else { | ||
| 287 | LOG_ERROR(Service_LDN, "Couldn't bind callback!"); | ||
| 288 | R_RETURN(ResultAirplaneModeEnabled); | ||
| 289 | } | ||
| 290 | |||
| 291 | lan_discovery.Initialize([&]() { OnEventFired(); }); | ||
| 292 | is_initialized = true; | ||
| 293 | R_SUCCEED(); | ||
| 294 | } | ||
| 295 | |||
| 296 | Result IUserLocalCommunicationService::Finalize() { | ||
| 297 | LOG_INFO(Service_LDN, "called"); | ||
| 298 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
| 299 | room_member->Unbind(ldn_packet_received); | ||
| 300 | } | ||
| 301 | |||
| 302 | is_initialized = false; | ||
| 303 | |||
| 304 | R_RETURN(lan_discovery.Finalize()); | ||
| 305 | } | ||
| 306 | |||
| 307 | Result IUserLocalCommunicationService::Initialize2(u32 version, ClientProcessId process_id) { | ||
| 308 | LOG_INFO(Service_LDN, "called, version={}, process_id={}", version, process_id.pid); | ||
| 309 | R_RETURN(Initialize(process_id)); | ||
| 310 | } | ||
| 311 | |||
| 312 | void IUserLocalCommunicationService::OnLDNPacketReceived(const Network::LDNPacket& packet) { | ||
| 313 | lan_discovery.ReceivePacket(packet); | ||
| 314 | } | ||
| 315 | |||
| 316 | void IUserLocalCommunicationService::OnEventFired() { | ||
| 317 | state_change_event->Signal(); | ||
| 318 | } | ||
| 319 | |||
| 320 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/user_local_communication_service.h b/src/core/hle/service/ldn/user_local_communication_service.h new file mode 100644 index 000000000..6698d10d2 --- /dev/null +++ b/src/core/hle/service/ldn/user_local_communication_service.h | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/ldn/lan_discovery.h" | ||
| 9 | #include "core/hle/service/ldn/ldn_types.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Network { | ||
| 17 | class RoomNetwork; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Service::LDN { | ||
| 21 | |||
| 22 | class IUserLocalCommunicationService final | ||
| 23 | : public ServiceFramework<IUserLocalCommunicationService> { | ||
| 24 | public: | ||
| 25 | explicit IUserLocalCommunicationService(Core::System& system_); | ||
| 26 | ~IUserLocalCommunicationService() override; | ||
| 27 | |||
| 28 | private: | ||
| 29 | Result GetState(Out<State> out_state); | ||
| 30 | |||
| 31 | Result GetNetworkInfo(OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info); | ||
| 32 | |||
| 33 | Result GetIpv4Address(Out<Ipv4Address> out_current_address, Out<Ipv4Address> out_subnet_mask); | ||
| 34 | |||
| 35 | Result GetDisconnectReason(Out<DisconnectReason> out_disconnect_reason); | ||
| 36 | |||
| 37 | Result GetSecurityParameter(Out<SecurityParameter> out_security_parameter); | ||
| 38 | |||
| 39 | Result GetNetworkConfig(Out<NetworkConfig> out_network_config); | ||
| 40 | |||
| 41 | Result AttachStateChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 42 | |||
| 43 | Result GetNetworkInfoLatestUpdate( | ||
| 44 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info, | ||
| 45 | OutArray<NodeLatestUpdate, BufferAttr_HipcPointer> out_node_latest_update); | ||
| 46 | |||
| 47 | Result Scan(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
| 48 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info); | ||
| 49 | |||
| 50 | Result ScanPrivate(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
| 51 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info); | ||
| 52 | |||
| 53 | Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction); | ||
| 54 | |||
| 55 | Result OpenAccessPoint(); | ||
| 56 | |||
| 57 | Result CloseAccessPoint(); | ||
| 58 | |||
| 59 | Result CreateNetwork(const CreateNetworkConfig& create_network_Config); | ||
| 60 | |||
| 61 | Result CreateNetworkPrivate(const CreateNetworkConfigPrivate& create_network_Config, | ||
| 62 | InArray<AddressEntry, BufferAttr_HipcPointer> address_list); | ||
| 63 | |||
| 64 | Result DestroyNetwork(); | ||
| 65 | |||
| 66 | Result SetAdvertiseData(InBuffer<BufferAttr_HipcAutoSelect> buffer_data); | ||
| 67 | |||
| 68 | Result SetStationAcceptPolicy(AcceptPolicy accept_policy); | ||
| 69 | |||
| 70 | Result AddAcceptFilterEntry(MacAddress mac_address); | ||
| 71 | |||
| 72 | Result OpenStation(); | ||
| 73 | |||
| 74 | Result CloseStation(); | ||
| 75 | |||
| 76 | Result Connect(const ConnectNetworkData& connect_data, | ||
| 77 | InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info); | ||
| 78 | |||
| 79 | Result Disconnect(); | ||
| 80 | |||
| 81 | Result Initialize(ClientProcessId aruid); | ||
| 82 | |||
| 83 | Result Finalize(); | ||
| 84 | |||
| 85 | Result Initialize2(u32 version, ClientProcessId aruid); | ||
| 86 | |||
| 87 | private: | ||
| 88 | /// Callback to parse and handle a received LDN packet. | ||
| 89 | void OnLDNPacketReceived(const Network::LDNPacket& packet); | ||
| 90 | void OnEventFired(); | ||
| 91 | |||
| 92 | KernelHelpers::ServiceContext service_context; | ||
| 93 | Kernel::KEvent* state_change_event; | ||
| 94 | Network::RoomNetwork& room_network; | ||
| 95 | LANDiscovery lan_discovery; | ||
| 96 | |||
| 97 | // Callback identifier for the OnLDNPacketReceived event. | ||
| 98 | Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received; | ||
| 99 | |||
| 100 | bool is_initialized{}; | ||
| 101 | }; | ||
| 102 | |||
| 103 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/omm/omm.cpp b/src/core/hle/service/omm/omm.cpp new file mode 100644 index 000000000..b95319e26 --- /dev/null +++ b/src/core/hle/service/omm/omm.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/omm/omm.h" | ||
| 5 | #include "core/hle/service/omm/operation_mode_manager.h" | ||
| 6 | #include "core/hle/service/omm/policy_manager_system.h" | ||
| 7 | #include "core/hle/service/omm/power_state_interface.h" | ||
| 8 | #include "core/hle/service/server_manager.h" | ||
| 9 | |||
| 10 | namespace Service::OMM { | ||
| 11 | |||
| 12 | void LoopProcess(Core::System& system) { | ||
| 13 | auto server_manager = std::make_unique<ServerManager>(system); | ||
| 14 | |||
| 15 | server_manager->RegisterNamedService("idle:sys", | ||
| 16 | std::make_shared<IPolicyManagerSystem>(system)); | ||
| 17 | server_manager->RegisterNamedService("omm", std::make_shared<IOperationModeManager>(system)); | ||
| 18 | server_manager->RegisterNamedService("spsm", std::make_shared<IPowerStateInterface>(system)); | ||
| 19 | ServerManager::RunServer(std::move(server_manager)); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/omm.h b/src/core/hle/service/omm/omm.h new file mode 100644 index 000000000..7bf04688a --- /dev/null +++ b/src/core/hle/service/omm/omm.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | namespace Core { | ||
| 7 | class System; | ||
| 8 | } | ||
| 9 | |||
| 10 | namespace Service::OMM { | ||
| 11 | |||
| 12 | void LoopProcess(Core::System& system); | ||
| 13 | |||
| 14 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/omm/operation_mode_manager.cpp index 66824e495..fe7ed84a7 100644 --- a/src/core/hle/service/am/omm.cpp +++ b/src/core/hle/service/omm/operation_mode_manager.cpp | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/omm.h" | 4 | #include "core/hle/service/omm/operation_mode_manager.h" |
| 5 | 5 | ||
| 6 | namespace Service::AM { | 6 | namespace Service::OMM { |
| 7 | 7 | ||
| 8 | OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} { | 8 | IOperationModeManager::IOperationModeManager(Core::System& system_) |
| 9 | : ServiceFramework{system_, "omm"} { | ||
| 9 | // clang-format off | 10 | // clang-format off |
| 10 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 11 | {0, nullptr, "GetOperationMode"}, | 12 | {0, nullptr, "GetOperationMode"}, |
| @@ -43,6 +44,6 @@ OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} { | |||
| 43 | RegisterHandlers(functions); | 44 | RegisterHandlers(functions); |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | OMM::~OMM() = default; | 47 | IOperationModeManager::~IOperationModeManager() = default; |
| 47 | 48 | ||
| 48 | } // namespace Service::AM | 49 | } // namespace Service::OMM |
diff --git a/src/core/hle/service/omm/operation_mode_manager.h b/src/core/hle/service/omm/operation_mode_manager.h new file mode 100644 index 000000000..32bc7b2f9 --- /dev/null +++ b/src/core/hle/service/omm/operation_mode_manager.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::OMM { | ||
| 13 | |||
| 14 | class IOperationModeManager final : public ServiceFramework<IOperationModeManager> { | ||
| 15 | public: | ||
| 16 | explicit IOperationModeManager(Core::System& system_); | ||
| 17 | ~IOperationModeManager() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/omm/policy_manager_system.cpp index 603515284..1cd6fd807 100644 --- a/src/core/hle/service/am/idle.cpp +++ b/src/core/hle/service/omm/policy_manager_system.cpp | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/idle.h" | 4 | #include "core/hle/service/omm/policy_manager_system.h" |
| 5 | 5 | ||
| 6 | namespace Service::AM { | 6 | namespace Service::OMM { |
| 7 | 7 | ||
| 8 | IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"} { | 8 | IPolicyManagerSystem::IPolicyManagerSystem(Core::System& system_) |
| 9 | : ServiceFramework{system_, "idle:sys"} { | ||
| 9 | // clang-format off | 10 | // clang-format off |
| 10 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 11 | {0, nullptr, "GetAutoPowerDownEvent"}, | 12 | {0, nullptr, "GetAutoPowerDownEvent"}, |
| @@ -20,6 +21,6 @@ IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"} | |||
| 20 | RegisterHandlers(functions); | 21 | RegisterHandlers(functions); |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | IdleSys::~IdleSys() = default; | 24 | IPolicyManagerSystem::~IPolicyManagerSystem() = default; |
| 24 | 25 | ||
| 25 | } // namespace Service::AM | 26 | } // namespace Service::OMM |
diff --git a/src/core/hle/service/omm/policy_manager_system.h b/src/core/hle/service/omm/policy_manager_system.h new file mode 100644 index 000000000..151ca0d2e --- /dev/null +++ b/src/core/hle/service/omm/policy_manager_system.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::OMM { | ||
| 13 | |||
| 14 | class IPolicyManagerSystem final : public ServiceFramework<IPolicyManagerSystem> { | ||
| 15 | public: | ||
| 16 | explicit IPolicyManagerSystem(Core::System& system_); | ||
| 17 | ~IPolicyManagerSystem() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/omm/power_state_interface.cpp index ec581e32b..22cac8259 100644 --- a/src/core/hle/service/am/spsm.cpp +++ b/src/core/hle/service/omm/power_state_interface.cpp | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/spsm.h" | 4 | #include "core/hle/service/omm/power_state_interface.h" |
| 5 | 5 | ||
| 6 | namespace Service::AM { | 6 | namespace Service::OMM { |
| 7 | 7 | ||
| 8 | SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} { | 8 | IPowerStateInterface::IPowerStateInterface(Core::System& system_) |
| 9 | : ServiceFramework{system_, "spsm"} { | ||
| 9 | // clang-format off | 10 | // clang-format off |
| 10 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 11 | {0, nullptr, "GetState"}, | 12 | {0, nullptr, "GetState"}, |
| @@ -26,6 +27,6 @@ SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} { | |||
| 26 | RegisterHandlers(functions); | 27 | RegisterHandlers(functions); |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | SPSM::~SPSM() = default; | 30 | IPowerStateInterface::~IPowerStateInterface() = default; |
| 30 | 31 | ||
| 31 | } // namespace Service::AM | 32 | } // namespace Service::OMM |
diff --git a/src/core/hle/service/omm/power_state_interface.h b/src/core/hle/service/omm/power_state_interface.h new file mode 100644 index 000000000..825a6512d --- /dev/null +++ b/src/core/hle/service/omm/power_state_interface.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::OMM { | ||
| 13 | |||
| 14 | class IPowerStateInterface final : public ServiceFramework<IPowerStateInterface> { | ||
| 15 | public: | ||
| 16 | explicit IPowerStateInterface(Core::System& system_); | ||
| 17 | ~IPowerStateInterface() override; | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index f68c3c686..fbdf217ba 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | 52 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" |
| 53 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 53 | #include "core/hle/service/nvnflinger/nvnflinger.h" |
| 54 | #include "core/hle/service/olsc/olsc.h" | 54 | #include "core/hle/service/olsc/olsc.h" |
| 55 | #include "core/hle/service/omm/omm.h" | ||
| 55 | #include "core/hle/service/pcie/pcie.h" | 56 | #include "core/hle/service/pcie/pcie.h" |
| 56 | #include "core/hle/service/pctl/pctl_module.h" | 57 | #include "core/hle/service/pctl/pctl_module.h" |
| 57 | #include "core/hle/service/pcv/pcv.h" | 58 | #include "core/hle/service/pcv/pcv.h" |
| @@ -266,6 +267,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system | |||
| 266 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); | 267 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); |
| 267 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); | 268 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); |
| 268 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); | 269 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); |
| 270 | kernel.RunOnGuestCoreProcess("omm", [&] { OMM::LoopProcess(system); }); | ||
| 269 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); | 271 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); |
| 270 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); | 272 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); |
| 271 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); | 273 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); |
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index b72788c6d..9444becce 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp | |||
| @@ -42,6 +42,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { | |||
| 42 | }; | 42 | }; |
| 43 | } | 43 | } |
| 44 | rescaleable = false; | 44 | rescaleable = false; |
| 45 | is_sparse = config.is_sparse != 0; | ||
| 45 | tile_width_spacing = config.tile_width_spacing; | 46 | tile_width_spacing = config.tile_width_spacing; |
| 46 | if (config.texture_type != TextureType::Texture2D && | 47 | if (config.texture_type != TextureType::Texture2D && |
| 47 | config.texture_type != TextureType::Texture2DNoMipmap) { | 48 | config.texture_type != TextureType::Texture2DNoMipmap) { |
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index 8a4cb0cbd..eb490a642 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h | |||
| @@ -41,6 +41,7 @@ struct ImageInfo { | |||
| 41 | bool downscaleable = false; | 41 | bool downscaleable = false; |
| 42 | bool forced_flushed = false; | 42 | bool forced_flushed = false; |
| 43 | bool dma_downloaded = false; | 43 | bool dma_downloaded = false; |
| 44 | bool is_sparse = false; | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | } // namespace VideoCommon | 47 | } // namespace VideoCommon |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 3a1cc060e..01c3561c9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -600,17 +600,17 @@ void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t siz | |||
| 600 | [&](ImageId id, Image&) { deleted_images.push_back(id); }); | 600 | [&](ImageId id, Image&) { deleted_images.push_back(id); }); |
| 601 | for (const ImageId id : deleted_images) { | 601 | for (const ImageId id : deleted_images) { |
| 602 | Image& image = slot_images[id]; | 602 | Image& image = slot_images[id]; |
| 603 | if (True(image.flags & ImageFlagBits::CpuModified)) { | 603 | if (False(image.flags & ImageFlagBits::CpuModified)) { |
| 604 | continue; | 604 | image.flags |= ImageFlagBits::CpuModified; |
| 605 | if (True(image.flags & ImageFlagBits::Tracked)) { | ||
| 606 | UntrackImage(image, id); | ||
| 607 | } | ||
| 605 | } | 608 | } |
| 606 | image.flags |= ImageFlagBits::CpuModified; | 609 | |
| 607 | if (True(image.flags & ImageFlagBits::Remapped)) { | 610 | if (True(image.flags & ImageFlagBits::Remapped)) { |
| 608 | continue; | 611 | continue; |
| 609 | } | 612 | } |
| 610 | image.flags |= ImageFlagBits::Remapped; | 613 | image.flags |= ImageFlagBits::Remapped; |
| 611 | if (True(image.flags & ImageFlagBits::Tracked)) { | ||
| 612 | UntrackImage(image, id); | ||
| 613 | } | ||
| 614 | } | 614 | } |
| 615 | } | 615 | } |
| 616 | 616 | ||
| @@ -1469,7 +1469,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA | |||
| 1469 | const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); | 1469 | const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); |
| 1470 | Image& new_image = slot_images[new_image_id]; | 1470 | Image& new_image = slot_images[new_image_id]; |
| 1471 | 1471 | ||
| 1472 | if (!gpu_memory->IsContinuousRange(new_image.gpu_addr, new_image.guest_size_bytes)) { | 1472 | if (!gpu_memory->IsContinuousRange(new_image.gpu_addr, new_image.guest_size_bytes) && |
| 1473 | new_info.is_sparse) { | ||
| 1473 | new_image.flags |= ImageFlagBits::Sparse; | 1474 | new_image.flags |= ImageFlagBits::Sparse; |
| 1474 | } | 1475 | } |
| 1475 | 1476 | ||
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index e28df10bd..28c3baf08 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -8,10 +8,7 @@ | |||
| 8 | #include "common/settings_enums.h" | 8 | #include "common/settings_enums.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applet_ae.h" | ||
| 12 | #include "core/hle/service/am/applet_manager.h" | 11 | #include "core/hle/service/am/applet_manager.h" |
| 13 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 14 | #include "core/hle/service/am/applet_oe.h" | ||
| 15 | #include "core/hle/service/sm/sm.h" | 12 | #include "core/hle/service/sm/sm.h" |
| 16 | #include "hid_core/frontend/emulated_controller.h" | 13 | #include "hid_core/frontend/emulated_controller.h" |
| 17 | #include "hid_core/hid_core.h" | 14 | #include "hid_core/hid_core.h" |
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index ce65b2bf1..d138b53c8 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp | |||
| @@ -54,13 +54,28 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 54 | QStringLiteral()); | 54 | QStringLiteral()); |
| 55 | 55 | ||
| 56 | // Core | 56 | // Core |
| 57 | INSERT(Settings, use_multi_core, tr("Multicore CPU Emulation"), QStringLiteral()); | 57 | INSERT( |
| 58 | INSERT(Settings, memory_layout_mode, tr("Memory Layout"), QStringLiteral()); | 58 | Settings, use_multi_core, tr("Multicore CPU Emulation"), |
| 59 | tr("This option increases CPU emulation thread use from 1 to the Switch’s maximum of 4.\n" | ||
| 60 | "This is mainly a debug option and shouldn’t be disabled.")); | ||
| 61 | INSERT( | ||
| 62 | Settings, memory_layout_mode, tr("Memory Layout"), | ||
| 63 | tr("Increases the amount of emulated RAM from the stock 4GB of the retail Switch to the " | ||
| 64 | "developer kit's 8/6GB.\nIt’s doesn’t improve stability or performance and is intended " | ||
| 65 | "to let big texture mods fit in emulated RAM.\nEnabling it will increase memory " | ||
| 66 | "use. It is not recommended to enable unless a specific game with a texture mod needs " | ||
| 67 | "it.")); | ||
| 59 | INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral()); | 68 | INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral()); |
| 60 | INSERT(Settings, speed_limit, tr("Limit Speed Percent"), QStringLiteral()); | 69 | INSERT(Settings, speed_limit, tr("Limit Speed Percent"), |
| 70 | tr("Controls the game's maximum rendering speed, but it’s up to each game if it runs " | ||
| 71 | "faster or not.\n200% for a 30 FPS game is 60 FPS, and for a " | ||
| 72 | "60 FPS game it will be 120 FPS.\nDisabling it means unlocking the framerate to the " | ||
| 73 | "maximum your PC can reach.")); | ||
| 61 | 74 | ||
| 62 | // Cpu | 75 | // Cpu |
| 63 | INSERT(Settings, cpu_accuracy, tr("Accuracy:"), QStringLiteral()); | 76 | INSERT(Settings, cpu_accuracy, tr("Accuracy:"), |
| 77 | tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless " | ||
| 78 | "you know what you are doing.")); | ||
| 64 | INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral()); | 79 | INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral()); |
| 65 | 80 | ||
| 66 | // Cpu Debug | 81 | // Cpu Debug |
| @@ -80,34 +95,75 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 80 | tr("This option improves the speed of 32 bits ASIMD floating-point functions by running " | 95 | tr("This option improves the speed of 32 bits ASIMD floating-point functions by running " |
| 81 | "with incorrect rounding modes.")); | 96 | "with incorrect rounding modes.")); |
| 82 | INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"), | 97 | INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"), |
| 83 | tr("This option improves speed by removing NaN checking. Please note this also reduces " | 98 | tr("This option improves speed by removing NaN checking.\nPlease note this also reduces " |
| 84 | "accuracy of certain floating-point instructions.")); | 99 | "accuracy of certain floating-point instructions.")); |
| 85 | INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"), | 100 | INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"), |
| 86 | tr("This option improves speed by eliminating a safety check before every memory " | 101 | tr("This option improves speed by eliminating a safety check before every memory " |
| 87 | "read/write " | 102 | "read/write in guest.\nDisabling it may allow a game to read/write the emulator's " |
| 88 | "in guest. Disabling it may allow a game to read/write the emulator's memory.")); | 103 | "memory.")); |
| 89 | INSERT( | 104 | INSERT( |
| 90 | Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"), | 105 | Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"), |
| 91 | tr("This option improves speed by relying only on the semantics of cmpxchg to ensure " | 106 | tr("This option improves speed by relying only on the semantics of cmpxchg to ensure " |
| 92 | "safety of exclusive access instructions. Please note this may result in deadlocks and " | 107 | "safety of exclusive access instructions.\nPlease note this may result in deadlocks and " |
| 93 | "other race conditions.")); | 108 | "other race conditions.")); |
| 94 | 109 | ||
| 95 | // Renderer | 110 | // Renderer |
| 96 | INSERT(Settings, renderer_backend, tr("API:"), QStringLiteral()); | 111 | INSERT( |
| 97 | INSERT(Settings, vulkan_device, tr("Device:"), QStringLiteral()); | 112 | Settings, renderer_backend, tr("API:"), |
| 98 | INSERT(Settings, shader_backend, tr("Shader Backend:"), QStringLiteral()); | 113 | tr("Switches between the available graphics APIs.\nVulkan is recommended in most cases.")); |
| 99 | INSERT(Settings, resolution_setup, tr("Resolution:"), QStringLiteral()); | 114 | INSERT(Settings, vulkan_device, tr("Device:"), |
| 115 | tr("This setting selects the GPU to use with the Vulkan backend.")); | ||
| 116 | INSERT(Settings, shader_backend, tr("Shader Backend:"), | ||
| 117 | tr("The shader backend to use for the OpenGL renderer.\nGLSL is the fastest in " | ||
| 118 | "performance and the best in rendering accuracy.\n" | ||
| 119 | "GLASM is a deprecated NVIDIA-only backend that offers much better shader building " | ||
| 120 | "performance at the cost of FPS and rendering accuracy.\n" | ||
| 121 | "SPIR-V compiles the fastest, but yields poor results on most GPU drivers.")); | ||
| 122 | INSERT(Settings, resolution_setup, tr("Resolution:"), | ||
| 123 | tr("Forces the game to render at a different resolution.\nHigher resolutions require " | ||
| 124 | "much more VRAM and bandwidth.\n" | ||
| 125 | "Options lower than 1X can cause rendering issues.")); | ||
| 100 | INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral()); | 126 | INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral()); |
| 101 | INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), QStringLiteral()); | 127 | INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), |
| 102 | INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), QStringLiteral()); | 128 | tr("Determines how sharpened the image will look while using FSR’s dynamic contrast.")); |
| 103 | INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), QStringLiteral()); | 129 | INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), |
| 104 | INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), QStringLiteral()); | 130 | tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a " |
| 105 | INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), QStringLiteral()); | 131 | "lower performance impact and can produce a better and more stable picture under " |
| 106 | INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), | 132 | "very low resolutions.")); |
| 107 | QStringLiteral()); | 133 | INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), |
| 108 | INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), QStringLiteral()); | 134 | tr("The method used to render the window in fullscreen.\nBorderless offers the best " |
| 109 | INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), QStringLiteral()); | 135 | "compatibility with the on-screen keyboard that some games request for " |
| 110 | INSERT(Settings, astc_recompression, tr("ASTC Recompression Method:"), QStringLiteral()); | 136 | "input.\nExclusive " |
| 137 | "fullscreen may offer better performance and better Freesync/Gsync support.")); | ||
| 138 | INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), | ||
| 139 | tr("Stretches the game to fit the specified aspect ratio.\nSwitch games only support " | ||
| 140 | "16:9, so custom game mods are required to get other ratios.\nAlso controls the " | ||
| 141 | "aspect ratio of captured screenshots.")); | ||
| 142 | INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), | ||
| 143 | tr("Allows saving shaders to storage for faster loading on following game " | ||
| 144 | "boots.\nDisabling " | ||
| 145 | "it is only intended for debugging.")); | ||
| 146 | INSERT( | ||
| 147 | Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), | ||
| 148 | tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); | ||
| 149 | INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), | ||
| 150 | tr("Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for " | ||
| 151 | "decoding, or perform no decoding at all (black screen on videos).\n" | ||
| 152 | "In most cases, GPU decoding provides the best performance.")); | ||
| 153 | INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), | ||
| 154 | tr("This option controls how ASTC textures should be decoded.\n" | ||
| 155 | "CPU: Use the CPU for decoding, slowest but safest method.\n" | ||
| 156 | "GPU: Use the GPU's compute shaders to decode ASTC textures, recommended for most " | ||
| 157 | "games and users.\n" | ||
| 158 | "CPU Asynchronously: Use the CPU to decode ASTC textures as they arrive. Completely " | ||
| 159 | "eliminates ASTC decoding\nstuttering at the cost of rendering issues while the " | ||
| 160 | "texture is being decoded.")); | ||
| 161 | INSERT( | ||
| 162 | Settings, astc_recompression, tr("ASTC Recompression Method:"), | ||
| 163 | tr("Almost all desktop and laptop dedicated GPUs lack support for ASTC textures, forcing " | ||
| 164 | "the emulator to decompress to an intermediate format any card supports, RGBA8.\n" | ||
| 165 | "This option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but " | ||
| 166 | "negatively affecting image quality.")); | ||
| 111 | INSERT( | 167 | INSERT( |
| 112 | Settings, vsync_mode, tr("VSync Mode:"), | 168 | Settings, vsync_mode, tr("VSync Mode:"), |
| 113 | tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " | 169 | tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " |
| @@ -121,22 +177,29 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 121 | 177 | ||
| 122 | // Renderer (Advanced Graphics) | 178 | // Renderer (Advanced Graphics) |
| 123 | INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), | 179 | INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), |
| 124 | QStringLiteral()); | 180 | tr("Slightly improves performance by moving presentation to a separate CPU thread.")); |
| 125 | INSERT( | 181 | INSERT( |
| 126 | Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"), | 182 | Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"), |
| 127 | tr("Runs work in the background while waiting for graphics commands to keep the GPU from " | 183 | tr("Runs work in the background while waiting for graphics commands to keep the GPU from " |
| 128 | "lowering its clock speed.")); | 184 | "lowering its clock speed.")); |
| 129 | INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), QStringLiteral()); | 185 | INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), |
| 130 | INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), QStringLiteral()); | 186 | tr("Controls the quality of texture rendering at oblique angles.\nIt’s a light setting " |
| 131 | INSERT( | 187 | "and safe to set at 16x on most GPUs.")); |
| 132 | Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"), | 188 | INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), |
| 133 | tr("Enables asynchronous shader compilation, which may reduce shader stutter. This feature " | 189 | tr("GPU emulation accuracy.\nMost games render fine with Normal, but High is still " |
| 134 | "is experimental.")); | 190 | "required for some.\nParticles tend to only render correctly with High " |
| 191 | "accuracy.\nExtreme should only be used for debugging.\nThis option can " | ||
| 192 | "be changed while playing.\nSome games may require booting on high to render " | ||
| 193 | "properly.")); | ||
| 194 | INSERT(Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"), | ||
| 195 | tr("Enables asynchronous shader compilation, which may reduce shader stutter.\nThis " | ||
| 196 | "feature " | ||
| 197 | "is experimental.")); | ||
| 135 | INSERT(Settings, use_fast_gpu_time, tr("Use Fast GPU Time (Hack)"), | 198 | INSERT(Settings, use_fast_gpu_time, tr("Use Fast GPU Time (Hack)"), |
| 136 | tr("Enables Fast GPU Time. This option will force most games to run at their highest " | 199 | tr("Enables Fast GPU Time. This option will force most games to run at their highest " |
| 137 | "native resolution.")); | 200 | "native resolution.")); |
| 138 | INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"), | 201 | INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"), |
| 139 | tr("Enables GPU vendor-specific pipeline cache. This option can improve shader loading " | 202 | tr("Enables GPU vendor-specific pipeline cache.\nThis option can improve shader loading " |
| 140 | "time significantly in cases where the Vulkan driver does not store pipeline cache " | 203 | "time significantly in cases where the Vulkan driver does not store pipeline cache " |
| 141 | "files internally.")); | 204 | "files internally.")); |
| 142 | INSERT( | 205 | INSERT( |
| @@ -157,19 +220,27 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 157 | // Renderer (Debug) | 220 | // Renderer (Debug) |
| 158 | 221 | ||
| 159 | // System | 222 | // System |
| 160 | INSERT(Settings, rng_seed, tr("RNG Seed"), QStringLiteral()); | 223 | INSERT(Settings, rng_seed, tr("RNG Seed"), |
| 224 | tr("Controls the seed of the random number generator.\nMainly used for speedrunning " | ||
| 225 | "purposes.")); | ||
| 161 | INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral()); | 226 | INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral()); |
| 162 | INSERT(Settings, device_name, tr("Device Name"), QStringLiteral()); | 227 | INSERT(Settings, device_name, tr("Device Name"), tr("The name of the emulated Switch.")); |
| 163 | INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), QStringLiteral()); | 228 | INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), |
| 229 | tr("This option allows to change the emulated clock of the Switch.\n" | ||
| 230 | "Can be used to manipulate time in games.")); | ||
| 164 | INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral()); | 231 | INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral()); |
| 165 | INSERT(Settings, custom_rtc_offset, QStringLiteral(" "), | 232 | INSERT(Settings, custom_rtc_offset, QStringLiteral(" "), |
| 166 | QStringLiteral("The number of seconds from the current unix time")); | 233 | QStringLiteral("The number of seconds from the current unix time")); |
| 167 | INSERT(Settings, language_index, tr("Language:"), | 234 | INSERT(Settings, language_index, tr("Language:"), |
| 168 | tr("Note: this can be overridden when region setting is auto-select")); | 235 | tr("Note: this can be overridden when region setting is auto-select")); |
| 169 | INSERT(Settings, region_index, tr("Region:"), QStringLiteral()); | 236 | INSERT(Settings, region_index, tr("Region:"), tr("The region of the emulated Switch.")); |
| 170 | INSERT(Settings, time_zone_index, tr("Time Zone:"), QStringLiteral()); | 237 | INSERT(Settings, time_zone_index, tr("Time Zone:"), |
| 238 | tr("The time zone of the emulated Switch.")); | ||
| 171 | INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral()); | 239 | INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral()); |
| 172 | INSERT(Settings, use_docked_mode, tr("Console Mode:"), QStringLiteral()); | 240 | INSERT(Settings, use_docked_mode, tr("Console Mode:"), |
| 241 | tr("Selects if the console is emulated in Docked or Handheld mode.\nGames will change " | ||
| 242 | "their resolution, details and supported controllers and depending on this setting.\n" | ||
| 243 | "Setting to Handheld can help improve performance for low end systems.")); | ||
| 173 | INSERT(Settings, current_user, QStringLiteral(), QStringLiteral()); | 244 | INSERT(Settings, current_user, QStringLiteral(), QStringLiteral()); |
| 174 | 245 | ||
| 175 | // Controls | 246 | // Controls |
| @@ -187,14 +258,19 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 187 | // Ui | 258 | // Ui |
| 188 | 259 | ||
| 189 | // Ui General | 260 | // Ui General |
| 190 | INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), QStringLiteral()); | 261 | INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), |
| 262 | tr("Ask to select a user profile on each boot, useful if multiple people use yuzu on " | ||
| 263 | "the same PC.")); | ||
| 191 | INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"), | 264 | INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"), |
| 192 | QStringLiteral()); | 265 | tr("This setting pauses yuzu when focusing other windows.")); |
| 193 | INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), | 266 | INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), |
| 194 | QStringLiteral()); | 267 | tr("This setting overrides game prompts asking to confirm stopping the game.\nEnabling " |
| 195 | INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), QStringLiteral()); | 268 | "it bypasses such prompts and directly exits the emulation.")); |
| 269 | INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), | ||
| 270 | tr("This setting hides the mouse after 2.5s of inactivity.")); | ||
| 196 | INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"), | 271 | INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"), |
| 197 | QStringLiteral()); | 272 | tr("Forcibly disables the use of the controller applet by guests.\nWhen a guest " |
| 273 | "attempts to open the controller applet, it is immediately closed.")); | ||
| 198 | 274 | ||
| 199 | // Linux | 275 | // Linux |
| 200 | INSERT(Settings, enable_gamemode, tr("Enable Gamemode"), QStringLiteral()); | 276 | INSERT(Settings, enable_gamemode, tr("Enable Gamemode"), QStringLiteral()); |
diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index 170f14684..1931dcd1f 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp | |||
| @@ -190,10 +190,8 @@ void ControllerShortcut::ControllerUpdateEvent(Core::HID::ControllerTriggerType | |||
| 190 | if (type != Core::HID::ControllerTriggerType::Button) { | 190 | if (type != Core::HID::ControllerTriggerType::Button) { |
| 191 | return; | 191 | return; |
| 192 | } | 192 | } |
| 193 | if (!Settings::values.controller_navigation) { | 193 | if (button_sequence.npad.raw == Core::HID::NpadButton::None && |
| 194 | return; | 194 | button_sequence.capture.raw == 0 && button_sequence.home.raw == 0) { |
| 195 | } | ||
| 196 | if (button_sequence.npad.raw == Core::HID::NpadButton::None) { | ||
| 197 | return; | 195 | return; |
| 198 | } | 196 | } |
| 199 | 197 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 13381fea8..dfa50006a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -44,9 +44,6 @@ | |||
| 44 | #include "core/frontend/applets/mii_edit.h" | 44 | #include "core/frontend/applets/mii_edit.h" |
| 45 | #include "core/frontend/applets/software_keyboard.h" | 45 | #include "core/frontend/applets/software_keyboard.h" |
| 46 | #include "core/hle/service/acc/profile_manager.h" | 46 | #include "core/hle/service/acc/profile_manager.h" |
| 47 | #include "core/hle/service/am/applet_ae.h" | ||
| 48 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 49 | #include "core/hle/service/am/applet_oe.h" | ||
| 50 | #include "core/hle/service/am/frontend/applets.h" | 47 | #include "core/hle/service/am/frontend/applets.h" |
| 51 | #include "core/hle/service/set/system_settings_server.h" | 48 | #include "core/hle/service/set/system_settings_server.h" |
| 52 | #include "frontend_common/content_manager.h" | 49 | #include "frontend_common/content_manager.h" |