android: Show notification permission page during setup

master
Charles Lombardo 2023-05-28 22:52:36 +07:00 committed by bunnei
parent 419daf770d
commit 7de86266fd
4 changed files with 151 additions and 59 deletions

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.fragments
import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.yuzu.yuzu_emu.R
class PermissionDeniedDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext())
.setPositiveButton(R.string.home_settings) { _: DialogInterface?, _: Int ->
openSettings()
}
.setNegativeButton(android.R.string.cancel, null)
.setTitle(R.string.permission_denied)
.setMessage(R.string.permission_denied_description)
.show()
}
private fun openSettings() {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", requireActivity().packageName, null)
intent.data = uri
startActivity(intent)
}
companion object {
const val TAG = "PermissionDeniedDialogFragment"
}
}

@ -3,6 +3,7 @@
package org.yuzu.yuzu_emu.fragments package org.yuzu.yuzu_emu.fragments
import android.Manifest
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -11,7 +12,9 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
@ -65,10 +68,6 @@ class SetupFragment : Fragment() {
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
pushNotificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
mainActivity = requireActivity() as MainActivity mainActivity = requireActivity() as MainActivity
homeViewModel.setNavigationVisibility(visible = false, animated = false) homeViewModel.setNavigationVisibility(visible = false, animated = false)
@ -88,7 +87,9 @@ class SetupFragment : Fragment() {
requireActivity().window.navigationBarColor = requireActivity().window.navigationBarColor =
ContextCompat.getColor(requireContext(), android.R.color.transparent) ContextCompat.getColor(requireContext(), android.R.color.transparent)
val pages = listOf( val pages = mutableListOf<SetupPage>()
pages.apply {
add(
SetupPage( SetupPage(
R.drawable.ic_yuzu_title, R.drawable.ic_yuzu_title,
R.string.welcome, R.string.welcome,
@ -98,7 +99,32 @@ class SetupFragment : Fragment() {
R.string.get_started, R.string.get_started,
{ pageForward() }, { pageForward() },
false false
), )
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
add(
SetupPage(
R.drawable.ic_notification,
R.string.notifications,
R.string.notifications_description,
0,
false,
R.string.give_permission,
{ permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) },
true,
R.string.notification_warning,
R.string.notification_warning_description,
0,
{
NotificationManagerCompat.from(requireContext())
.areNotificationsEnabled()
}
)
)
}
add(
SetupPage( SetupPage(
R.drawable.ic_key, R.drawable.ic_key,
R.string.keys, R.string.keys,
@ -112,7 +138,9 @@ class SetupFragment : Fragment() {
R.string.install_prod_keys_warning_description, R.string.install_prod_keys_warning_description,
R.string.install_prod_keys_warning_help, R.string.install_prod_keys_warning_help,
{ File(DirectoryInitialization.userDirectory + "/keys/prod.keys").exists() } { File(DirectoryInitialization.userDirectory + "/keys/prod.keys").exists() }
), )
)
add(
SetupPage( SetupPage(
R.drawable.ic_controller, R.drawable.ic_controller,
R.string.games, R.string.games,
@ -130,7 +158,9 @@ class SetupFragment : Fragment() {
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty() preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty()
} }
), )
)
add(
SetupPage( SetupPage(
R.drawable.ic_check, R.drawable.ic_check,
R.string.done, R.string.done,
@ -142,6 +172,8 @@ class SetupFragment : Fragment() {
false false
) )
) )
}
binding.viewPager2.apply { binding.viewPager2.apply {
adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages) adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages)
offscreenPageLimit = 2 offscreenPageLimit = 2
@ -225,9 +257,15 @@ class SetupFragment : Fragment() {
_binding = null _binding = null
} }
private val pushNotificationPermissionLauncher = @RequiresApi(Build.VERSION_CODES.TIRAMISU)
private val permissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { registerForActivityResult(ActivityResultContracts.RequestPermission()) {
// TODO: Show proper notification request reason and confirmation if (!it && !shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
PermissionDeniedDialogFragment().show(
childFragmentManager,
PermissionDeniedDialogFragment.TAG
)
}
} }
private fun finishSetup() { private fun finishSetup() {

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z" />
</vector>

@ -48,6 +48,13 @@
<string name="install_prod_keys_warning">Skip adding keys?</string> <string name="install_prod_keys_warning">Skip adding keys?</string>
<string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string> <string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string>
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string> <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
<string name="notifications">Notifications</string>
<string name="notifications_description">Grant the notification permission with the button below.</string>
<string name="give_permission">Grant permission</string>
<string name="notification_warning">Skip granting the notification permission?</string>
<string name="notification_warning_description">yuzu won\'t be able to notify you of important information.</string>
<string name="permission_denied">Permission denied</string>
<string name="permission_denied_description">You denied this permission too many times and now you have to manually grant it in system settings.</string>
<string name="about">About</string> <string name="about">About</string>
<string name="about_description">Build version, credits, and more</string> <string name="about_description">Build version, credits, and more</string>
<string name="warning_help">Help</string> <string name="warning_help">Help</string>