MOB-40 changed the settings view and fixed menu notifications

This commit is contained in:
Henrik Lepson 2021-11-25 16:13:35 +02:00
parent 1138abcb11
commit 762a8c8cc2
10 changed files with 124 additions and 80 deletions

View File

@ -38,6 +38,8 @@ class HomeFragment : Fragment() {
// The ID card reader mode is enabled on the home fragment when can is saved.
private var canSaved: Boolean = false
// Is the app used for authentication
private var auth: Boolean = false
override fun onCreateView(
inflater: LayoutInflater,
@ -50,57 +52,57 @@ class HomeFragment : Fragment() {
return binding!!.root
}
// TODO: Split the contents of onViewCreated methods into smaller separate methods
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initialChecks()
updateAction(canSaved) // Should be called later
var auth = false
if (requireActivity().intent.data?.getQueryParameter("action") != null) {
// Currently we only support authentication not signing.
auth = true
}
val mobile = requireActivity().intent.getBooleanExtra("mobile", false)
if (auth || mobile){
try {
if (mobile) {
// We use !! because we want an exception when something is not right.
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
} else { //Website
var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!!
// TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back.
challenge = challenge.replace(" ", "+")
intentParams.setChallenge(challenge)
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
}
} catch (e: Exception) {
// There was a problem with parameters, which means that authentication is not possible.
val resultIntent = Intent()
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
requireActivity().finish()
}
goToTheNextFragment(true, mobile)
if (auth || mobile) {
startAuthentication(mobile)
} else {
updateAction(canSaved)
}
}
/**
* Starts the process of interacting with the ID card by sending user to the CAN fragment.
*
* NOTE: This method should only be used for authentication flow in the future.
*/
private fun goToTheNextFragment(auth: Boolean = false, mobile: Boolean = false) {
private fun goToTheNextFragment(mobile: Boolean = false) {
(activity as MainActivity).menuAvailable = false
if (auth) {
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = false, auth = true, mobile = mobile)
findNavController().navigate(action)
} else {
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true, auth = false, mobile = mobile)
findNavController().navigate(action)
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(auth = true, mobile = mobile)
findNavController().navigate(action)
}
/**
* Method that starts the authentication use case.
*/
private fun startAuthentication(mobile: Boolean) {
try {
if (mobile) {
// We use !! to get extras because we want an exception to be thrown when something is missing.
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
} else { //Website
var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!!
// TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back.
challenge = challenge.replace(" ", "+")
intentParams.setChallenge(challenge)
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
}
} catch (e: Exception) {
// There was a problem with parameters, which means that authentication is not possible.
// In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on
// before eventual error.
val resultIntent = Intent()
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
requireActivity().finish()
}
goToTheNextFragment(mobile)
}
/**
@ -160,11 +162,22 @@ class HomeFragment : Fragment() {
} else {
binding!!.detectionActionText.text = getString(R.string.action_detect_unavailable)
}
}
// TODO: When error occurs it should be cleared within a reasonable timeframe and it should be possible to detect cards again
// TODO: Listen to system broadcasts to detect if NFC is turned on/off during when the app is working
/**
* Resets the error message and allows the user to try again
*/
private fun reset() {
binding!!.buttonAgain.setOnClickListener {
updateAction(canSaved)
binding!!.buttonAgain.visibility = View.GONE
}
binding!!.buttonAgain.visibility = View.VISIBLE
}
/**
* Method that enables the NFC reader mode, which allows the app to communicate with the ID card and retrieve information.
*/
private fun enableReaderMode() {
val adapter = NfcAdapter.getDefaultAdapter(activity)
if (adapter == null) {
@ -192,8 +205,16 @@ class HomeFragment : Fragment() {
}
} catch (e: Exception) {
when(e) {
is TagLostException -> requireActivity().runOnUiThread { binding!!.detectionActionText.text = getString(R.string.id_card_removed_early)}
else -> requireActivity().runOnUiThread { binding!!.detectionActionText.text = getString(R.string.nfc_reading_error) }
is TagLostException -> requireActivity().runOnUiThread {
binding!!.detectionActionText.text = getString(R.string.id_card_removed_early)
reset()
}
else -> requireActivity().runOnUiThread {
binding!!.detectionActionText.text = getString(R.string.nfc_reading_error)
viewModel.deleteCan(requireContext())
canState()
reset()
}
}
} finally {
adapter.disableReaderMode(activity)

View File

@ -20,6 +20,8 @@ class MainActivity : AppCompatActivity() {
// If true the settings menu can be accessed from the toolbar in the upper part of the screen.
var menuAvailable: Boolean = true
var inMenu: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
@ -41,9 +43,12 @@ class MainActivity : AppCompatActivity() {
if (menuAvailable) {
navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
menuAvailable = false
inMenu = true
true
} else {
Toast.makeText(this, getString(R.string.unavailable), Toast.LENGTH_SHORT).show()
if (!inMenu) {
Toast.makeText(this, getString(R.string.unavailable), Toast.LENGTH_SHORT).show()
}
false
}
}

View File

@ -8,6 +8,7 @@ import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.tarkvaraprojekt.mobileauthapp.MainActivity
import com.tarkvaraprojekt.mobileauthapp.R
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentSettingsBinding
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
@ -67,6 +68,7 @@ class SettingsFragment : Fragment() {
viewModel.deleteCan(requireContext())
showCanField()
} else {
(activity as MainActivity).inMenu = false
val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(saving = true)
findNavController().navigate(action)
}
@ -101,6 +103,7 @@ class SettingsFragment : Fragment() {
viewModel.deletePin(requireContext())
showPinField()
} else {
(activity as MainActivity).inMenu = false
val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(saving = true)
findNavController().navigate(action)
}
@ -130,6 +133,7 @@ class SettingsFragment : Fragment() {
* Navigates back to home fragment.
*/
private fun backToHome() {
(activity as MainActivity).inMenu = false
findNavController().navigate(R.id.action_settingsFragment_to_homeFragment)
}

View File

@ -100,4 +100,16 @@
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/button_again"
android:textSize="@dimen/regular_text"
android:text="@string/try_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginStart="@dimen/margin_huge"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/id_card_detection"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -89,20 +89,6 @@
</LinearLayout>
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_big"
android:fontFamily="sans-serif"
android:text="@string/button_cancel"
android:textSize="@dimen/regular_text"
app:layout_constraintEnd_toStartOf="@+id/button_continue"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/save_layout" />
<Button
android:id="@+id/button_continue"
android:layout_width="wrap_content"
@ -111,9 +97,18 @@
android:fontFamily="sans-serif"
android:text="@string/continue_button"
android:textSize="@dimen/regular_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button_cancel"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/save_layout" />
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_big"
android:fontFamily="sans-serif"
android:text="@string/button_cancel"
android:textSize="@dimen/regular_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_continue" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="12dp"
android:layout_margin="@dimen/padding"
tools:context=".menu.SettingsFragment">
<com.google.android.material.card.MaterialCardView
@ -22,44 +22,46 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
android:padding="@dimen/padding_small">
<TextView
android:id="@+id/can_saved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:padding="12dp"
android:textSize="@dimen/regular_text"
android:padding="@dimen/margin_small"
android:text="@string/saved_can" />
<Button
android:id="@+id/can_menu_action"
android:layout_margin="12dp"
android:textSize="15sp"
android:layout_margin="@dimen/margin_small"
android:textSize="@dimen/regular_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/pin_saved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:padding="12dp"
android:textSize="@dimen/regular_text"
android:padding="@dimen/margin_small"
android:text="@string/saved_pin"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/pin_menu_action"
android:layout_margin="12dp"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:orientation="vertical">
<Button
android:id="@+id/pin_menu_show"
android:layout_margin="12dp"
android:textSize="15sp"
android:layout_marginHorizontal="@dimen/margin"
android:layout_marginVertical="@dimen/margin_small"
android:textSize="@dimen/regular_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<Button
android:id="@+id/pin_menu_action"
android:layout_marginHorizontal="@dimen/margin"
android:layout_marginVertical="@dimen/margin_small"
android:textSize="@dimen/regular_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
@ -69,8 +71,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/return_text"
android:layout_margin="24dp"
android:textSize="15sp"
android:layout_marginVertical="@dimen/margin"
android:layout_marginStart="@dimen/padding"
android:textSize="@dimen/regular_text"
app:layout_constraintTop_toBottomOf="@id/settings_card"
app:layout_constraintStart_toStartOf="parent" />

View File

@ -97,5 +97,6 @@
<string name="action_detect_unavailable">CAN must be added before ID card can be detected</string>
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
<string name="id_card_removed_early">ID card was removed too eraly</string>
<string name="id_card_removed_early">ID card was removed too early</string>
<string name="try_again">Try Again</string>
</resources>

View File

@ -95,5 +95,6 @@
<string name="action_detect_unavailable">CAN must be added before ID card can be detected</string>
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
<string name="id_card_removed_early">ID card was removed too eraly</string>
<string name="id_card_removed_early">ID card was removed too early</string>
<string name="try_again">Try Again</string>
</resources>

View File

@ -3,6 +3,7 @@
<dimen name="margin_small">4dp</dimen>
<dimen name="margin">8dp</dimen>
<dimen name="margin_big">16dp</dimen>
<dimen name="margin_huge">32dp</dimen>
<dimen name="padding_tiny">8dp</dimen>
<dimen name="padding_small">16dp</dimen>
<dimen name="padding">24dp</dimen>

View File

@ -95,5 +95,6 @@
<string name="action_detect_unavailable">CAN must be added before ID card can be detected</string>
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
<string name="id_card_removed_early">ID card was removed too eraly</string>
<string name="id_card_removed_early">ID card was removed too early</string>
<string name="try_again">Try Again</string>
</resources>