Add TitleId TextView in App Dialog

This commit is contained in:
Dima 2022-11-22 19:11:37 +03:00 committed by Billy Laws
parent b08fcd7027
commit 5a9a2861df
9 changed files with 54 additions and 6 deletions

View File

@ -51,6 +51,7 @@ extern "C" JNIEXPORT jint JNICALL Java_emu_skyline_loader_RomFile_populate(JNIEn
jclass clazz{env->GetObjectClass(thiz)};
jfieldID applicationNameField{env->GetFieldID(clazz, "applicationName", "Ljava/lang/String;")};
jfieldID applicationTitleIdField{env->GetFieldID(clazz, "applicationTitleId", "Ljava/lang/String;")};
jfieldID applicationAuthorField{env->GetFieldID(clazz, "applicationAuthor", "Ljava/lang/String;")};
jfieldID rawIconField{env->GetFieldID(clazz, "rawIcon", "[B")};
jfieldID applicationVersionField{env->GetFieldID(clazz, "applicationVersion", "Ljava/lang/String;")};
@ -62,6 +63,7 @@ extern "C" JNIEXPORT jint JNICALL Java_emu_skyline_loader_RomFile_populate(JNIEn
env->SetObjectField(thiz, applicationNameField, env->NewStringUTF(loader->nacp->GetApplicationName(language).c_str()));
env->SetObjectField(thiz, applicationVersionField, env->NewStringUTF(loader->nacp->GetApplicationVersion().c_str()));
env->SetObjectField(thiz, applicationTitleIdField, env->NewStringUTF(loader->nacp->GetSaveDataOwnerId().c_str()));
env->SetObjectField(thiz, applicationAuthorField, env->NewStringUTF(loader->nacp->GetApplicationPublisher(language).c_str()));
auto icon{loader->GetIcon(language)};

View File

@ -61,7 +61,7 @@ namespace skyline::kernel {
name = nacp->GetApplicationName(nacp->GetFirstSupportedTitleLanguage());
if (publisher.empty())
publisher = nacp->GetApplicationPublisher(nacp->GetFirstSupportedTitleLanguage());
Logger::InfoNoPrefix(R"(Starting "{}" v{} by "{}")", name, nacp->GetApplicationVersion(), publisher);
Logger::InfoNoPrefix(R"(Starting "{}" ({}) v{} by "{}")", name, nacp->GetSaveDataOwnerId(), nacp->GetApplicationVersion(), publisher);
}
process->InitializeHeapTls();

View File

@ -34,6 +34,11 @@ namespace skyline::vfs {
return std::string(applicationPublisher.as_string(true));
}
std::string NACP::GetSaveDataOwnerId() {
auto applicationTitleId{nacpContents.saveDataOwnerId};
return fmt::format("{:016X}", applicationTitleId);
}
std::string NACP::GetApplicationPublisher(language::ApplicationLanguage language) {
auto applicationPublisher{span(nacpContents.titleEntries.at(static_cast<size_t>(language)).applicationPublisher)};
return std::string(applicationPublisher.as_string(true));

View File

@ -49,6 +49,8 @@ namespace skyline::vfs {
std::string GetApplicationVersion();
std::string GetSaveDataOwnerId();
std::string GetApplicationPublisher(language::ApplicationLanguage language);
};
}

View File

@ -19,6 +19,7 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.snackbar.Snackbar
import emu.skyline.data.AppItem
import emu.skyline.databinding.AppDialogBinding
import emu.skyline.loader.LoaderResult
@ -66,6 +67,7 @@ class AppDialog : BottomSheetDialogFragment() {
binding.gameIcon.setImageBitmap(item.icon ?: missingIcon)
binding.gameTitle.text = item.title
binding.gameVersion.text = item.version ?: item.loaderResultString(requireContext())
binding.gameTitleId.text = item.titleId
binding.gameAuthor.text = item.author
binding.gamePlay.isEnabled = item.loaderResult == LoaderResult.Success
@ -91,6 +93,13 @@ class AppDialog : BottomSheetDialogFragment() {
shortcutManager.requestPinShortcut(info.build(), null)
}
binding.gameTitleId.setOnLongClickListener {
val clipboard = requireActivity().getSystemService(android.content.Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
clipboard.setPrimaryClip(android.content.ClipData.newPlainText("Title ID", item.titleId))
Snackbar.make(binding.root, getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT).show()
true
}
dialog?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BUTTON_B && event.action == KeyEvent.ACTION_UP) {
dialog?.onBackPressed()

View File

@ -29,6 +29,11 @@ data class AppItem(private val meta : AppEntry) : DataItem() {
*/
val title get() = meta.name
/**
* The title ID of the application
*/
val titleId get() = meta.titleId
/**
* The application version
*/

View File

@ -66,6 +66,7 @@ enum class LoaderResult(val value : Int) {
data class AppEntry(
var name : String,
var version : String?,
var titleId : String?,
var author : String?,
var icon : Bitmap?,
var format : RomFormat,
@ -76,7 +77,7 @@ data class AppEntry(
val nameIndex : Int = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
cursor.getString(nameIndex)
}!!.dropLast(format.name.length + 1), null, null, null, format, uri, loaderResult)
}!!.dropLast(format.name.length + 1), null, null, null, null, format, uri, loaderResult)
private fun writeObject(output : ObjectOutputStream) {
output.writeUTF(name)
@ -85,6 +86,9 @@ data class AppEntry(
output.writeBoolean(version != null)
if (version != null)
output.writeUTF(version)
output.writeBoolean(titleId != null)
if (titleId != null)
output.writeUTF(titleId)
output.writeBoolean(author != null)
if (author != null)
output.writeUTF(author)
@ -105,6 +109,8 @@ data class AppEntry(
uri = Uri.parse(input.readUTF())
if (input.readBoolean())
version = input.readUTF()
if (input.readBoolean())
titleId = input.readUTF()
if (input.readBoolean())
author = input.readUTF()
loaderResult = LoaderResult.get(input.readInt())
@ -129,6 +135,11 @@ internal class RomFile(context : Context, format : RomFormat, uri : Uri, systemL
*/
private var applicationName : String? = null
/**
* @note This field is filled in by native code
*/
private var applicationTitleId : String? = null
/**
* @note This field is filled in by native code
*/
@ -158,9 +169,11 @@ internal class RomFile(context : Context, format : RomFormat, uri : Uri, systemL
appEntry = applicationName?.let { name ->
applicationVersion?.let { version ->
applicationAuthor?.let { author ->
rawIcon?.let { icon ->
AppEntry(name, version, author, BitmapFactory.decodeByteArray(icon, 0, icon.size), format, uri, result)
applicationTitleId?.let { titleId ->
applicationAuthor?.let { author ->
rawIcon?.let { icon ->
AppEntry(name, version, titleId, author, BitmapFactory.decodeByteArray(icon, 0, icon.size), format, uri, result)
}
}
}
}

View File

@ -54,7 +54,7 @@
tools:text="The Legend of Zelda: Breath of the Wild" />
<TextView
android:id="@+id/game_version"
android:id="@+id/game_title_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
@ -62,6 +62,17 @@
android:textSize="14sp"
app:layout_constraintStart_toStartOf="@id/game_title"
app:layout_constraintTop_toBottomOf="@id/game_title"
tools:text="0100000000010000" />
<TextView
android:id="@+id/game_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="@android:color/tertiary_text_light"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="@id/game_title_id"
app:layout_constraintTop_toBottomOf="@id/game_title_id"
tools:text="1.0.0" />
<TextView

View File

@ -3,6 +3,7 @@
<!-- Common -->
<string name="search">Search</string>
<string name="error">An error has occurred</string>
<string name="copied_to_clipboard">Copied to clipboard</string>
<!-- Toolbar Main -->
<string name="settings">Settings</string>
<string name="share_logs">Share Logs</string>