android: Add key check
This commit is contained in:
		@@ -614,6 +614,11 @@ object NativeLibrary {
 | 
			
		||||
     */
 | 
			
		||||
    external fun clearFilesystemProvider()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if all necessary keys are present for decryption
 | 
			
		||||
     */
 | 
			
		||||
    external fun areKeysPresent(): Boolean
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Button type for use in onTouchEvent
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ import androidx.preference.PreferenceManager
 | 
			
		||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
 | 
			
		||||
import com.google.android.material.transition.MaterialFadeThrough
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import org.yuzu.yuzu_emu.NativeLibrary
 | 
			
		||||
import java.io.File
 | 
			
		||||
import org.yuzu.yuzu_emu.R
 | 
			
		||||
import org.yuzu.yuzu_emu.YuzuApplication
 | 
			
		||||
@@ -162,7 +163,7 @@ class SetupFragment : Fragment() {
 | 
			
		||||
                    R.string.install_prod_keys_warning_help,
 | 
			
		||||
                    {
 | 
			
		||||
                        val file = File(DirectoryInitialization.userDirectory + "/keys/prod.keys")
 | 
			
		||||
                        if (file.exists()) {
 | 
			
		||||
                        if (file.exists() && NativeLibrary.areKeysPresent()) {
 | 
			
		||||
                            StepState.COMPLETE
 | 
			
		||||
                        } else {
 | 
			
		||||
                            StepState.INCOMPLETE
 | 
			
		||||
@@ -347,7 +348,8 @@ class SetupFragment : Fragment() {
 | 
			
		||||
    val getProdKey =
 | 
			
		||||
        registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
 | 
			
		||||
            if (result != null) {
 | 
			
		||||
                if (mainActivity.processKey(result)) {
 | 
			
		||||
                mainActivity.processKey(result)
 | 
			
		||||
                if (NativeLibrary.areKeysPresent()) {
 | 
			
		||||
                    keyCallback.onStepCompleted()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,9 @@ class HomeViewModel : ViewModel() {
 | 
			
		||||
    private val _reloadPropertiesList = MutableStateFlow(false)
 | 
			
		||||
    val reloadPropertiesList get() = _reloadPropertiesList.asStateFlow()
 | 
			
		||||
 | 
			
		||||
    private val _checkKeys = MutableStateFlow(false)
 | 
			
		||||
    val checkKeys = _checkKeys.asStateFlow()
 | 
			
		||||
 | 
			
		||||
    var navigatedToSetup = false
 | 
			
		||||
 | 
			
		||||
    fun setNavigationVisibility(visible: Boolean, animated: Boolean) {
 | 
			
		||||
@@ -66,4 +69,8 @@ class HomeViewModel : ViewModel() {
 | 
			
		||||
    fun reloadPropertiesList(reload: Boolean) {
 | 
			
		||||
        _reloadPropertiesList.value = reload
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setCheckKeys(value: Boolean) {
 | 
			
		||||
        _checkKeys.value = value
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
 | 
			
		||||
 | 
			
		||||
    override var themeId: Int = 0
 | 
			
		||||
 | 
			
		||||
    private val CHECKED_DECRYPTION = "CheckedDecryption"
 | 
			
		||||
    private var checkedDecryption = false
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        val splashScreen = installSplashScreen()
 | 
			
		||||
        splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
 | 
			
		||||
@@ -75,6 +78,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
 | 
			
		||||
        binding = ActivityMainBinding.inflate(layoutInflater)
 | 
			
		||||
        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)
 | 
			
		||||
        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)
 | 
			
		||||
@@ -158,6 +183,21 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
 | 
			
		||||
        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) {
 | 
			
		||||
        navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment)
 | 
			
		||||
        (binding.navigationView as NavigationBarView).setupWithNavController(navController)
 | 
			
		||||
@@ -349,6 +389,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
 | 
			
		||||
                    R.string.install_keys_success,
 | 
			
		||||
                    Toast.LENGTH_SHORT
 | 
			
		||||
                ).show()
 | 
			
		||||
                homeViewModel.setCheckKeys(true)
 | 
			
		||||
                gamesViewModel.reloadGames(true)
 | 
			
		||||
                return true
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -399,6 +440,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
 | 
			
		||||
                        firmwarePath.deleteRecursively()
 | 
			
		||||
                        cacheFirmwareDir.copyRecursively(firmwarePath, true)
 | 
			
		||||
                        NativeLibrary.initializeSystem(true)
 | 
			
		||||
                        homeViewModel.setCheckKeys(true)
 | 
			
		||||
                        getString(R.string.save_file_imported_success)
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (e: Exception) {
 | 
			
		||||
 
 | 
			
		||||
@@ -913,4 +913,10 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env,
 | 
			
		||||
    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"
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,9 @@
 | 
			
		||||
    <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_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 -->
 | 
			
		||||
    <string name="applets">Applet launcher</string>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user