3
0
Fork 0
forked from suyu/suyu

android: Add key check

This commit is contained in:
t895 2024-01-24 12:37:26 -05:00
parent bc317a9807
commit b8be8dff69
6 changed files with 67 additions and 2 deletions

View file

@ -614,6 +614,11 @@ object NativeLibrary {
*/ */
external fun clearFilesystemProvider() external fun clearFilesystemProvider()
/**
* Checks if all necessary keys are present for decryption
*/
external fun areKeysPresent(): Boolean
/** /**
* Button type for use in onTouchEvent * Button type for use in onTouchEvent
*/ */

View file

@ -31,6 +31,7 @@ import androidx.preference.PreferenceManager
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.yuzu.yuzu_emu.NativeLibrary
import java.io.File import java.io.File
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication import org.yuzu.yuzu_emu.YuzuApplication
@ -162,7 +163,7 @@ class SetupFragment : Fragment() {
R.string.install_prod_keys_warning_help, R.string.install_prod_keys_warning_help,
{ {
val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys") val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys")
if (file.exists()) { if (file.exists() && NativeLibrary.areKeysPresent()) {
StepState.COMPLETE StepState.COMPLETE
} else { } else {
StepState.INCOMPLETE StepState.INCOMPLETE
@ -347,7 +348,8 @@ class SetupFragment : Fragment() {
val getProdKey = val getProdKey =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
if (result != null) { if (result != null) {
if (mainActivity.processKey(result)) { mainActivity.processKey(result)
if (NativeLibrary.areKeysPresent()) {
keyCallback.onStepCompleted() keyCallback.onStepCompleted()
} }
} }

View file

@ -31,6 +31,9 @@ class HomeViewModel : ViewModel() {
private val _reloadPropertiesList = MutableStateFlow(false) private val _reloadPropertiesList = MutableStateFlow(false)
val reloadPropertiesList get() = _reloadPropertiesList.asStateFlow() val reloadPropertiesList get() = _reloadPropertiesList.asStateFlow()
private val _checkKeys = MutableStateFlow(false)
val checkKeys = _checkKeys.asStateFlow()
var navigatedToSetup = false var navigatedToSetup = false
fun setNavigationVisibility(visible: Boolean, animated: Boolean) { fun setNavigationVisibility(visible: Boolean, animated: Boolean) {
@ -66,4 +69,8 @@ class HomeViewModel : ViewModel() {
fun reloadPropertiesList(reload: Boolean) { fun reloadPropertiesList(reload: Boolean) {
_reloadPropertiesList.value = reload _reloadPropertiesList.value = reload
} }
fun setCheckKeys(value: Boolean) {
_checkKeys.value = value
}
} }

View file

@ -64,6 +64,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
override var themeId: Int = 0 override var themeId: Int = 0
private val CHECKED_DECRYPTION = "CheckedDecryption"
private var checkedDecryption = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen() val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady } splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
@ -75,6 +78,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
if (savedInstanceState != null) {
checkedDecryption = savedInstanceState.getBoolean(CHECKED_DECRYPTION)
}
if (!checkedDecryption) {
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
if (!firstTimeSetup) {
checkKeys()
}
checkedDecryption = true
}
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
@ -150,6 +165,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
} }
} }
} }
launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
homeViewModel.checkKeys.collect {
if (it) {
checkKeys()
homeViewModel.setCheckKeys(false)
}
}
}
}
} }
// Dismiss previous notifications (should not happen unless a crash occurred) // Dismiss previous notifications (should not happen unless a crash occurred)
@ -158,6 +183,21 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
setInsets() setInsets()
} }
private fun checkKeys() {
if (!NativeLibrary.areKeysPresent()) {
MessageDialogFragment.newInstance(
titleId = R.string.keys_missing,
descriptionId = R.string.keys_missing_description,
helpLinkId = R.string.keys_missing_help
).show(supportFragmentManager, MessageDialogFragment.TAG)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(CHECKED_DECRYPTION, checkedDecryption)
}
fun finishSetup(navController: NavController) { fun finishSetup(navController: NavController) {
navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment) navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment)
(binding.navigationView as NavigationBarView).setupWithNavController(navController) (binding.navigationView as NavigationBarView).setupWithNavController(navController)
@ -349,6 +389,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
R.string.install_keys_success, R.string.install_keys_success,
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
homeViewModel.setCheckKeys(true)
gamesViewModel.reloadGames(true) gamesViewModel.reloadGames(true)
return true return true
} else { } else {
@ -399,6 +440,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
firmwarePath.deleteRecursively() firmwarePath.deleteRecursively()
cacheFirmwareDir.copyRecursively(firmwarePath, true) cacheFirmwareDir.copyRecursively(firmwarePath, true)
NativeLibrary.initializeSystem(true) NativeLibrary.initializeSystem(true)
homeViewModel.setCheckKeys(true)
getString(R.string.save_file_imported_success) getString(R.string.save_file_imported_success)
} }
} catch (e: Exception) { } catch (e: Exception) {

View file

@ -913,4 +913,10 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env,
EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries(); EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries();
} }
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_areKeysPresent(JNIEnv* env, jobject jobj) {
auto& system = EmulationSession::GetInstance().System();
system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
return ContentManager::AreKeysPresent();
}
} // extern "C" } // extern "C"

View file

@ -144,6 +144,9 @@
<string name="no_save_data_found">No save data found</string> <string name="no_save_data_found">No save data found</string>
<string name="verify_installed_content">Verify installed content</string> <string name="verify_installed_content">Verify installed content</string>
<string name="verify_installed_content_description">Checks all installed content for corruption</string> <string name="verify_installed_content_description">Checks all installed content for corruption</string>
<string name="keys_missing">Encryption keys are missing</string>
<string name="keys_missing_description">Firmware and retail games cannot be decrypted</string>
<string name="keys_missing_help">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<!-- Applet launcher strings --> <!-- Applet launcher strings -->
<string name="applets">Applet launcher</string> <string name="applets">Applet launcher</string>