Skip to content

feat(libSceIme): show a notice when PSN-only system dialogs open - #13701

Merged
adriadam10 merged 28 commits into
boykopovar:mainfrom
MarcZX10:feat/psn-unavailable-dialogs
Oct 31, 2026
Merged

adriadam10 merged 28 commits into
boykopovar:mainfrom
MarcZX10:feat/psn-unavailable-dialogs

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

Adds ANYPS5_PSN_DIALOGS (show or silent, default silent). Some system dialogs need PlayStation Network. Today their Open succeeds and the dialog finishes at once with the cancelled result, so the title sees nothing happen. With ANYPS5_PSN_DIALOGS=show, a successful Open displays a short host notice on the modal dialog that PR #12379 added to libSceIme (one OK button, takes the controller until answered). The status and result codes are unchanged in both modes.

Libraries that call the shared notice after their Open checks pass (status and result unchanged):

  • libSceNpProfileDialog: sceNpProfileDialogOpen, sceNpProfileDialogOpenA
  • libSceNpFriendListDialog: sceNpFriendListDialogOpenA
  • libSceNpCommerce (PlayStation Store): sceNpCommerceDialogOpen, sceNpCommerceDialogOpen2
  • libSceNpSnsFacebookDialog: sceNpSnsFacebookDialogOpen
  • libSceInvitationDialog: sceInvitationDialogOpen (recipients are PSN online or account ids: shadPS4 src/core/libraries/invitation_dialog/invitation_dialog.cpp at 1d8004a22feb0d5cc58828bac066018e80b6d73f, lines 158-159 and 269-285)
  • libSceNpAuthAuthorizedAppDialog: sceNpAuthAuthorizedAppDialogOpen
  • libSceWebBrowserDialog: sceWebBrowserDialogOpen, sceWebBrowserDialogOpenForPredeterminedContent, with a generic text ("This system feature is not available in AnyPS5."). No source ties this dialog to PlayStation Network, so its notice does not claim it.

Not included, with the reason:

  • libSceLoginDialog: its user list takes local user ids (KytyPS5 src/libs/dialog.cpp at 4919fdb6e6e28f46f1f5df8cf931a7a0823cb93f, LoginDialog), not PSN.
  • libSceSigninDialog: no source states that it is PSN-only; it takes a local user id.
  • libSceSocialScreenDialog: its debt entry describes a second-screen viewer, not PSN.
  • libSceGameCustomDataDialog, libScePlayerSelectionDialog, libSceCdlgPlayerReview: no source found that ties them to PSN.
  • Dialogs whose Open already throws (NotImplemented_nid_no_patch) or that have no Open (libSceNpSnsYouTubeDialog, libSceNpEulaDialog, libScePlayerInvitationDialog, libSceSocialScreen): no silent close to replace.

Default decision: notices are opt-in. A default notice would put a modal over every title that opens these dialogs, take the controller until OK, and change what the console-side behaviour is taken to be; nothing measured on a console supports either. With silent, unset or empty, nothing changes: the notice code never calls the modal dialog.

Notice behaviour (libSceIme PsnDialogNotice.hpp/.cpp): refused when no presenter is registered, while another modal dialog or notice is showing, and within 2000 ms of the previous notice; a refused offer does not start the interval. Invalid values (anything other than show, silent, unset or empty, including Show and 1) stop the title at its first offer with an error naming the variable.

Debt: each library's debt doc records that the console's own display is not measured and that the notice wording is AnyPS5's.

Overlap (checked against current main e49d43d, 2026-10-31, with tools/pr_overlap.py --branch):

Tested

Head 8f3cb16c8d (28 commits; the merge of upstream/main at 91db3f7 is kept). Debian 12, Linux 6.1.0-54-amd64, gcc 12.2.0, Release, BUILD_TESTING=ON. This host lacks some CPU extensions the PS5 target has, so the scratch archive relaxes the host CPU gate (as build-template.sh does).

Run and measured:

  • The 17 tests of the touched libraries on the branch: 17/17 passed (ctest after the negative controls and a rebuild of the 17 targets; the same 17 passed before the controls).
  • ime_dialog_pad_keyboard and guest_ime_dialog (existing libSceImeDialog tests, built for this run): 2/2 passed on the branch.
  • Baseline on upstream/main a09a85c925 (git worktree, same flags, same 17 targets built from clean main): the 17 pre-existing tests among these pass 17/17. Per test, every pre-existing test passes on both trees; psn_dialog_notice and psn_dialog_notice_mode exist only on the branch and pass.
  • Negative controls: one hook or rule mutated at a time in the scratch archive, the 17 targets rebuilt, the 17 tests run, source restored from git, and the tree rebuilt and rerun (17/17 again). Each row lists the tests that failed; every other test passed.
Control Mutation Failing test(s)
NC1 removes the notice call in libSceNpProfileDialog guest_np_profile_dialog
NC2 removes the notice call in libSceNpFriendListDialog guest_np_friend_list_dialog
NC3 removes the notice call in sceNpCommerceDialogOpen guest_np_commerce_dialog
NC4 removes the notice call in sceNpCommerceDialogOpen2 guest_np_commerce_dialog
NC5 removes the notice call in libSceNpSnsFacebookDialog guest_np_sns_facebook_dialog
NC6 removes the notice call in libSceInvitationDialog guest_invitation_dialog
NC7 removes the notice call in libSceNpAuthAuthorizedAppDialog guest_np_auth_authorized_app_dialog
NC8 web browser Open claims PSN (kind changed to PsnFeature) guest_web_browser_dialog
NC9 removes the notice call in sceWebBrowserDialogOpenForPredeterminedContent guest_web_browser_dialog
NC10 default-silent gate removed (notice shown with the variable unset) psn_dialog_notice and the seven hook tests above (8 in total)
NC11 mode parser accepts Show psn_dialog_notice_mode
NC12 interval check disabled (second notice not refused) psn_dialog_notice

Caveat for NC1 to NC12: the test helpers abort without printing the assertion, so the failing assertion is inferred from which test fails, not read from a message.

Static and environment checks (run on this candidate):

  • git diff --check upstream/main...HEAD: clean.
  • tools/check_conventions.py --base upstream/main: all checks passed.
  • tools/pr_abi_audit.py (run manually from the candidate tree, whose snapshot lacks the tool): status passed.
  • tools/pr_test_quality.py (run manually on the nine changed test files): 9 "possible-unregistered-cpp-test" findings. All are false positives: each file is registered in CMake through ${LIBS_INCLUDE_DIR}/tests/<file>.
  • tools/pr_precheck.py (no-build): the diff check and conventions steps pass; its ABI-audit and test-quality steps report missing files in the candidate snapshot, which is why they were run by hand above.
  • python3 tools/env_reference.py --check: fails with the same single line on upstream/main a09a85c925 and on this branch: error: APS5_PAD_SPEAKER_FALLBACK_DB has a row in docs/dev/ENVIRONMENT.md but the code no longer reads it / 0 name(s) undocumented, 1 stale. Known baseline failure; this branch adds no new one.
  • Mergeability: git merge-tree of this branch with current main e49d43d6 (101 commits after the baseline) reports no conflicts. This is a tree-level check; the build and tests above are on a09a85c925.

Not run: Windows, macOS, real console, hardware GPU, the full ctest suite, a build and test on e49d43d6, and the 41 PRs listed under Overlap (not compared).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

Add ParsePsnDialogNoticeMode, which reads the opt-in that decides whether a
PSN-only system dialog shows a host notice. Unset or empty and silent select
the current behaviour (no notice); show selects the notice. Any other value
throws an error that names the variable and the value, so the title stops at
first use instead of guessing.
Check that an unset or empty variable and silent select no notice, show
selects it, and that the spellings that are not exactly show or silent
(case, spaces, numbers, yes/on) are refused with an error naming the
variable and the value.
Add PsnDialogNoticeOffer, the one place the PSN-only dialog libraries call
when their Open succeeds. With ANYPS5_PSN_DIALOGS unset or silent it does
nothing and never touches the modal dialog. With show it opens an OK
notice on the modal dialog of PR boykopovar#12379, which is refused when no presenter
is registered, when another modal dialog is showing, and when a notice was
offered less than two seconds before. Refused offers leave the rate-limit
state alone, so a later offer can still show. The notice text says the
feature needs PlayStation Network, or, for the generic kind, that the system
feature is not available; it never names a title.
Check that no notice is shown without a presenter and in silent mode, that
the PSN and generic texts reach the modal dialog with one OK button, that a
notice is owned by its own library and captures input, that a second offer
is refused while one shows, that a notice is refused within two seconds of
the last one and allowed at two seconds, and that a refused offer does not
start the interval.
Open and OpenA send the notice after the parameter checks pass and the
dialog moves to FINISHED, so a refused call shows nothing. The status and
the result are unchanged. With ANYPS5_PSN_DIALOGS unset the notice is not
shown, as before. The library links libSceIme for the shared notice.
Check that silent mode and an unset variable show nothing, that show mode
shows the PSN notice once for Open and once for OpenA, that a refused null
parameter and an Open that throws show nothing, and that no notice is
shown when no presenter is registered. The guest test links libSceIme.
Add the row for the mode that shows a notice when a PlayStation Network
dialog opens, with its unset and invalid behaviour. The row is in its own
libSceIme section because the variable is read in that library.
…ist opens

OpenA sends the notice after its null check passes and the dialog moves to
FINISHED. Status and result are unchanged, and nothing is shown unless
ANYPS5_PSN_DIALOGS is show.
…k dialog opens

Open sends the notice after its null check passes and the dialog moves to
FINISHED. Status and result are unchanged, and nothing is shown unless
ANYPS5_PSN_DIALOGS is show.
Open and Open2 send the notice after their parameter checks pass and the
dialog moves to FINISHED, so a refused call shows nothing. Status, result
and the store icon calls are unchanged. The store is the PlayStation Store,
which needs PlayStation Network; nothing is shown unless ANYPS5_PSN_DIALOGS
is show.
…ialog opens

Open sends the notice after its checks pass and the dialog moves to
FINISHED. Status and result are unchanged, and nothing is shown unless
ANYPS5_PSN_DIALOGS is show.
… dialog opens

Open sends the notice after its parameter checks pass and the dialog moves
to FINISHED. The recipients are PlayStation Network online or account ids
(shadPS4 invitation_dialog.cpp, friend picker). Status and result are
unchanged, and nothing is shown unless ANYPS5_PSN_DIALOGS is show.
…opens

Open and OpenForPredeterminedContent send the generic notice after their
checks pass and the dialog moves to FINISHED. The browser's open-parameter
layout has no public source and nothing ties this dialog to PlayStation
Network, so the notice says only that the system feature is not available.
Status and result are unchanged, and nothing is shown unless
ANYPS5_PSN_DIALOGS is show.
Check that silent mode and an unset variable show nothing, that show mode
shows the PSN notice once when OpenA succeeds, that a null parameter shows
nothing, and that no notice is shown without a presenter. The guest test
links libSceIme.
Check that silent mode shows nothing, that show mode shows the PSN notice
when Open succeeds, that a null parameter shows nothing, and that no notice
is shown without a presenter. The guest test links libSceIme.
Check that silent mode shows nothing, that show mode shows the PSN notice
when Open and Open2 succeed with a valid store parameter, that a null
parameter shows nothing, and that no notice is shown without a presenter.
The guest test links libSceIme.
Check that silent mode shows nothing, that show mode shows the PSN notice
once when Open succeeds, that a null parameter shows nothing, and that the
dialog still finishes with the same result. The guest test links libSceIme.
Check that silent mode shows nothing, that show mode shows the PSN notice
when Open succeeds with a valid parameter, and that a null parameter shows
nothing. The guest test links libSceIme.
Check that silent mode shows nothing, that show mode shows the generic
notice for Open and OpenForPredeterminedContent, and that a null parameter
shows nothing. The guest test links libSceIme.
Add a section on ANYPS5_PSN_DIALOGS: which dialogs finish silently without
PlayStation Network, what show displays, how the notice takes input and how
often it appears, and what the other values do.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
The debt entry says that the notice shown with ANYPS5_PSN_DIALOGS=show is
AnyPS5's, and that what the console displays for this call without PlayStation
Network is not measured.
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 9676 docs/dev/ENVIRONMENT.md L531
PR 12804 docs/dev/debt/libSceNpFriendListDialog.md L4-5
PR 12893 core/libs/prx/libSceNpSnsFacebookDialog/Export.cpp L35-39
core/libs/tests/GuestNpSnsFacebookDialog.cpp L2, L17-18, L77

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 1896 docs/dev/ENVIRONMENT.md
PR 3786 docs/user/USAGE.md
PR 4472 docs/dev/ENVIRONMENT.md
PR 5021 docs/user/USAGE.md
PR 5925 docs/user/USAGE.md
PR 6185 docs/dev/ENVIRONMENT.md
PR 6186 docs/dev/ENVIRONMENT.md
PR 6501 docs/dev/ENVIRONMENT.md
PR 6924 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 7449 docs/dev/ENVIRONMENT.md
PR 7457 docs/dev/ENVIRONMENT.md
PR 7514 docs/dev/ENVIRONMENT.md
PR 7604 docs/dev/ENVIRONMENT.md
PR 7642 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 7922 docs/dev/ENVIRONMENT.md
PR 8004 docs/dev/ENVIRONMENT.md
PR 8484 docs/dev/ENVIRONMENT.md
PR 8542 docs/dev/ENVIRONMENT.md
PR 8887 docs/dev/ENVIRONMENT.md
PR 9012 docs/dev/ENVIRONMENT.md
PR 9176 docs/dev/ENVIRONMENT.md
PR 9248 docs/dev/ENVIRONMENT.md
PR 9287 docs/dev/ENVIRONMENT.md
PR 9289 docs/dev/ENVIRONMENT.md
PR 9345 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 9356 docs/dev/ENVIRONMENT.md
PR 9387 docs/dev/ENVIRONMENT.md
PR 9508 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 9712 docs/dev/ENVIRONMENT.md
PR 9852 docs/dev/ENVIRONMENT.md
PR 9875 docs/dev/ENVIRONMENT.md
PR 9898 docs/dev/ENVIRONMENT.md
PR 10026 docs/dev/ENVIRONMENT.md
PR 10043 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 10069 docs/dev/ENVIRONMENT.md
PR 10193 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 10194 docs/dev/ENVIRONMENT.md
PR 10382 docs/dev/ENVIRONMENT.md
PR 10442 docs/dev/ENVIRONMENT.md
PR 10443 docs/dev/ENVIRONMENT.md
PR 10472 docs/dev/ENVIRONMENT.md
PR 10720 docs/dev/ENVIRONMENT.md
PR 10750 docs/dev/ENVIRONMENT.md
PR 10757 docs/dev/ENVIRONMENT.md
PR 10792 docs/user/USAGE.md
PR 10846 docs/dev/ENVIRONMENT.md
PR 10861 docs/user/USAGE.md
PR 10894 docs/dev/ENVIRONMENT.md
PR 11351 docs/dev/ENVIRONMENT.md
PR 11435 docs/dev/ENVIRONMENT.md
PR 11436 docs/dev/ENVIRONMENT.md
PR 12120 docs/dev/ENVIRONMENT.md
PR 12323 docs/dev/ENVIRONMENT.md
PR 12324 docs/dev/ENVIRONMENT.md
PR 12478 docs/dev/ENVIRONMENT.md
PR 12544 docs/dev/ENVIRONMENT.md
PR 12567 docs/dev/ENVIRONMENT.md
PR 12568 docs/dev/ENVIRONMENT.md
PR 12662 docs/dev/ENVIRONMENT.md
PR 12745 docs/dev/ENVIRONMENT.md
PR 12746 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 12786 docs/user/USAGE.md
PR 12840 docs/dev/ENVIRONMENT.md
PR 12921 docs/dev/ENVIRONMENT.md
PR 12980 docs/dev/ENVIRONMENT.md
PR 13044 docs/dev/ENVIRONMENT.md
PR 13159 docs/dev/ENVIRONMENT.md
PR 13263 docs/dev/ENVIRONMENT.md
PR 13774 docs/dev/ENVIRONMENT.md
PR 13793 docs/dev/ENVIRONMENT.md
PR 13809 docs/dev/ENVIRONMENT.md
PR 13858 docs/dev/ENVIRONMENT.md
PR 13863 docs/dev/ENVIRONMENT.md
PR 13920 docs/dev/ENVIRONMENT.md
PR 13928 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 13929 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 13931 docs/dev/ENVIRONMENT.md
docs/user/USAGE.md
PR 14051 docs/dev/ENVIRONMENT.md

@adriadam10 adriadam10 self-assigned this Oct 31, 2026
@adriadam10
adriadam10 merged commit 0836dfd into boykopovar:main Oct 31, 2026
12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the notice hook in each of the eight Open paths (offered only after the argument checks pass, status and result unchanged), the default-silent gate, the strict ANYPS5_PSN_DIALOGS parsing, the 2000 ms interval, the ctest registration of the new tests, the ENVIRONMENT.md/USAGE.md entries and the debt lines (env_reference.py --check passes); merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants