android: Add key check
This commit is contained in:
		@@ -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
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user