diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt index 4819fb2..ed47ad4 100644 --- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt +++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt @@ -1,6 +1,9 @@ package com.tarkvaraprojekt.mobileauthapp import android.content.Intent +import android.nfc.NfcAdapter +import android.nfc.TagLostException +import android.nfc.tech.IsoDep import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -10,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController +import com.tarkvaraprojekt.mobileauthapp.NFC.Comms import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel @@ -31,6 +35,9 @@ class HomeFragment : Fragment() { private var binding: FragmentHomeBinding? = null + // The ID card reader mode is enabled on the home fragment when can is saved. + private var canSaved: Boolean = false + override fun onCreateView( inflater: LayoutInflater, @@ -43,9 +50,11 @@ 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. @@ -53,7 +62,6 @@ class HomeFragment : Fragment() { } 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. @@ -77,27 +85,15 @@ class HomeFragment : Fragment() { goToTheNextFragment(true, mobile) } - binding!!.beginButton.setOnClickListener { goToTheNextFragment() } - } - - /** - * Method where all the initial checks that should be done before any user input is accepted should be added. - */ - private fun initialChecks() { - viewModel.checkCan(requireContext()) - viewModel.checkPin(requireContext()) - displayStates() } /** * 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) { - // Making settings menu inactive (activity as MainActivity).menuAvailable = false - // Currently saving is true because the application is not yet integrated with - // other applications or websites. - // TODO: Check the navigation action default values. Not everything has to be declared explicitly. if (auth) { val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = false, auth = true, mobile = mobile) findNavController().navigate(action) @@ -107,16 +103,6 @@ class HomeFragment : Fragment() { } } - /** - * Displays texts that inform the user whether the CAN and PIN 1 are saved on the device or not. - * This might help the user to save some time as checking menu is not necessary unless the user - * wishes to make changes to the saved CAN or PIN 1. - */ - private fun displayStates() { - canState() - pinState() - } - /** * Checks the state of the CAN, saved or not saved. Updates the text and logo. */ @@ -124,9 +110,11 @@ class HomeFragment : Fragment() { if (viewModel.userCan.length == 6) { binding!!.canStatusText.text = getString(R.string.can_status_saved) binding!!.canStatusLogo.setImageResource(R.drawable.ic_check_logo) + canSaved = true } else { binding!!.canStatusText.text = getString(R.string.can_status_negative) binding!!.canStatusLogo.setImageResource(R.drawable.ic_info_logo) + canSaved = false } } @@ -143,6 +131,78 @@ class HomeFragment : Fragment() { } } + /** + * Displays texts that inform the user whether the CAN and PIN 1 are saved on the device or not. + * This might help the user to save some time as checking menu is not necessary unless the user + * wishes to make changes to the saved CAN or PIN 1. + */ + private fun displayStates() { + canState() + pinState() + } + + /** + * Method where all the initial checks that should be completed before any user input is accepted should be conducted. + */ + private fun initialChecks() { + viewModel.checkCan(requireContext()) + viewModel.checkPin(requireContext()) + displayStates() + } + + /** + * Informs user whether the ID card can be detected or not. + */ + private fun updateAction(canIsSaved: Boolean) { + if (canIsSaved) { + binding!!.detectionActionText.text = getString(R.string.action_detect) + enableReaderMode() + } 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 + private fun enableReaderMode() { + val adapter = NfcAdapter.getDefaultAdapter(activity) + if (adapter == null) { + binding!!.detectionActionText.text = getString(R.string.nfc_not_available) + } else { + adapter.enableReaderMode(activity, { tag -> + requireActivity().runOnUiThread { + binding!!.detectionActionText.text = getString(R.string.card_detected) + } + val card = IsoDep.get(tag) + card.timeout = 32768 + card.use { + try { + val comms = Comms(it, viewModel.userCan) + val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8)) + viewModel.setUserFirstName(response[1]) + viewModel.setUserLastName(response[0]) + viewModel.setUserIdentificationNumber(response[2]) + viewModel.setGender(response[3]) + viewModel.setCitizenship(response[4]) + viewModel.setExpiration(response[5]) + requireActivity().runOnUiThread { + val action = HomeFragmentDirections.actionHomeFragmentToUserFragment() + findNavController().navigate(action) + } + } 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) } + } + } finally { + adapter.disableReaderMode(activity) + } + } + }, NfcAdapter.FLAG_READER_NFC_A, null) + } + } + override fun onDestroyView() { super.onDestroyView() binding = null diff --git a/MobileAuthApp/app/src/main/res/layout/fragment_auth.xml b/MobileAuthApp/app/src/main/res/layout/fragment_auth.xml index 59652f3..3da81db 100644 --- a/MobileAuthApp/app/src/main/res/layout/fragment_auth.xml +++ b/MobileAuthApp/app/src/main/res/layout/fragment_auth.xml @@ -4,14 +4,14 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="24dp" + android:padding="@dimen/padding" tools:context=".AuthFragment"> + android:padding="@dimen/padding"> + android:textSize="@dimen/regular_text" /> @@ -60,9 +60,9 @@ android:id="@+id/next_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="24dp" + android:layout_marginTop="@dimen/margin_big" android:text="@string/next_text" - android:textSize="15sp" + android:textSize="@dimen/regular_text" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/cancel_button" app:layout_constraintTop_toBottomOf="@id/card_view" /> @@ -71,9 +71,9 @@ android:id="@+id/cancel_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="24dp" + android:layout_marginTop="@dimen/margin_big" android:text="@string/cancel_text" - android:textSize="15sp" + android:textSize="@dimen/regular_text" app:layout_constraintEnd_toStartOf="@id/next_button" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/card_view" /> diff --git a/MobileAuthApp/app/src/main/res/layout/fragment_home.xml b/MobileAuthApp/app/src/main/res/layout/fragment_home.xml index dae476b..5de026f 100644 --- a/MobileAuthApp/app/src/main/res/layout/fragment_home.xml +++ b/MobileAuthApp/app/src/main/res/layout/fragment_home.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="24dp" + android:padding="@dimen/padding" tools:context=".HomeFragment"> @@ -32,14 +32,14 @@ @@ -51,7 +51,7 @@ android:id="@+id/pin_status" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="12dp" + android:layout_margin="@dimen/margin_big" app:strokeWidth="1dp" app:strokeColor="@color/stroke_color" app:cardElevation="0dp"> @@ -63,14 +63,14 @@ @@ -80,15 +80,24 @@ -