diff --git a/app/build.gradle b/app/build.gradle index 550fbc3..6cf02ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId "au.gov.health.covidsafe" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 78 - versionName "1.13.0" + versionCode 80 + versionName "1.14.0" buildConfigField "String", "GITHASH", "\"${getGitHash()}\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/debug/java/au/gov/health/covidsafe/PeekActivity.kt b/app/src/debug/java/au/gov/health/covidsafe/PeekActivity.kt index 698600f..5d5f2ad 100644 --- a/app/src/debug/java/au/gov/health/covidsafe/PeekActivity.kt +++ b/app/src/debug/java/au/gov/health/covidsafe/PeekActivity.kt @@ -134,7 +134,9 @@ class PeekActivity : AppCompatActivity() { stop.visibility = View.GONE delete.visibility = View.GONE } - + btn_de_active_token.setOnClickListener { + Preference.putEncrypterJWTToken(this, "123456789" ) + } } private fun showPushTokenOnDebugBuild() { diff --git a/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt b/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt index 027eae5..a74d475 100644 --- a/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt +++ b/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt @@ -16,14 +16,17 @@ import au.gov.health.covidsafe.ui.utils.Utils import au.gov.health.covidsafe.utils.NetworkConnectionCheck import com.google.android.gms.tasks.OnCompleteListener import com.google.firebase.iid.FirebaseInstanceId +import kotlinx.android.synthetic.main.view_home_setup_incomplete.* private const val TAG = "HomeActivity" +private const val UNAUTHORIZED = "Unauthorized" class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectionListener { var isAppUpdateAvailableLiveData = MutableLiveData() var appUpdateAvailableMessageResponseLiveData = MutableLiveData() var isWindowFocusChangeLiveData = MutableLiveData() + var isJWTCorrupted = MutableLiveData() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -60,6 +63,13 @@ class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectio private fun checkAndUpdateHealthStatus() { GetMessagesScheduler.scheduleGetMessagesJob { + + if (it.errorBodyMessage.equals(UNAUTHORIZED)) { + isJWTCorrupted.postValue(true) + } else{ + isJWTCorrupted.postValue(false) + } + val isAppWithLatestVersion = it.messages.isNullOrEmpty() isAppUpdateAvailableLiveData.postValue(isAppWithLatestVersion) CentralLog.d(TAG, "isAppWithLatestVersion: $it") @@ -75,7 +85,7 @@ class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectio body, "https://play.google.com/store/apps/details?id=au.gov.health.covidsafe") ) - )) + , it.message, it.forceappupgrade, it.errorBodyMessage)) } } } diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/MessagesResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/MessagesResponse.kt index b530394..0a7adaf 100644 --- a/app/src/main/java/au/gov/health/covidsafe/networking/response/MessagesResponse.kt +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/MessagesResponse.kt @@ -3,7 +3,10 @@ package au.gov.health.covidsafe.networking.response import androidx.annotation.Keep @Keep -data class MessagesResponse(val messages: List?) +data class MessagesResponse(val messages: List?, val message: String?, val forceappupgrade: Boolean?, val errorBodyMessage:String?) @Keep -data class Message(val title: String, val body: String, val destination: String) \ No newline at end of file +data class Message(val title: String, val body: String, val destination: String) + +@Keep +data class ErrorMessage(val message: String?) diff --git a/app/src/main/java/au/gov/health/covidsafe/preference/Preference.kt b/app/src/main/java/au/gov/health/covidsafe/preference/Preference.kt index 831f57e..cadbdfa 100644 --- a/app/src/main/java/au/gov/health/covidsafe/preference/Preference.kt +++ b/app/src/main/java/au/gov/health/covidsafe/preference/Preference.kt @@ -37,6 +37,7 @@ object Preference { private const val IS_DEVICE_NAME_CHANGE_PROMPT_DISPLAYED = "IS_DEVICE_NAME_CHANGE_DISPLAYED" private const val BUILD_NUMBER_FOR_POP_UP_NOTIFICATION = "BUILD_NUMBER_FOR_POP_UP_NOTIFICATION" private const val TURN_CASE_NUMBER = "TURN_CASE_NUMBER" + private const val IS_REREGISTER = "IS_REREGISTER" fun putDeviceID(context: Context, value: String) { context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) @@ -126,6 +127,16 @@ object Preference { .getBoolean(IS_ONBOARDED, false) } + fun putIsReRegister(context: Context, value: Boolean) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putBoolean(IS_REREGISTER, value).apply() + } + + fun isReRegister(context: Context): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getBoolean(IS_REREGISTER, false) + } + fun putHasDeviceNameNotificationDisplayed(context: Context, value: Boolean) { context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) .edit().putBoolean(HAS_DEVICE_NAME_NOTIFICATION_DISPLAYED, value).apply() diff --git a/app/src/main/java/au/gov/health/covidsafe/scheduler/GetMessagesScheduler.kt b/app/src/main/java/au/gov/health/covidsafe/scheduler/GetMessagesScheduler.kt index d8225ef..3ac963f 100644 --- a/app/src/main/java/au/gov/health/covidsafe/scheduler/GetMessagesScheduler.kt +++ b/app/src/main/java/au/gov/health/covidsafe/scheduler/GetMessagesScheduler.kt @@ -7,7 +7,6 @@ import android.app.job.JobService import android.content.ComponentName import android.content.Context import au.gov.health.covidsafe.BuildConfig -import au.gov.health.covidsafe.preference.Preference import au.gov.health.covidsafe.app.TracerApp import au.gov.health.covidsafe.extensions.isBatteryOptimizationDisabled import au.gov.health.covidsafe.extensions.isBlueToothEnabled @@ -15,10 +14,13 @@ import au.gov.health.covidsafe.extensions.isLocationEnabledOnDevice import au.gov.health.covidsafe.extensions.isLocationPermissionAllowed import au.gov.health.covidsafe.factory.NetworkFactory.Companion.awsClient import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.networking.response.ErrorMessage import au.gov.health.covidsafe.networking.response.MessagesResponse +import au.gov.health.covidsafe.preference.Preference import au.gov.health.covidsafe.scheduler.GetMessagesScheduler.mostRecentRecordTimestamp import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase +import com.google.gson.Gson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay @@ -175,9 +177,14 @@ object GetMessagesScheduler { response.body()?.let { CentralLog.d(TAG, "onResponse() MessagesResponse = $it") - messagesResponseCallback?.invoke(it) } + } else if (responseCode == 401) { + response.errorBody()?.let { + val errorMessage: ErrorMessage = Gson().fromJson(it.string(), ErrorMessage::class.java) + val messageResponse = MessagesResponse(emptyList(), null, false, errorMessage.message) + messagesResponseCallback?.invoke(messageResponse) + } } else { CentralLog.w(TAG, "onResponse() got error response code = $responseCode.") } diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/base/BindingAdapter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/base/BindingAdapter.kt index 8ce365a..4096aa9 100644 --- a/app/src/main/java/au/gov/health/covidsafe/ui/base/BindingAdapter.kt +++ b/app/src/main/java/au/gov/health/covidsafe/ui/base/BindingAdapter.kt @@ -50,7 +50,7 @@ fun setDateFormat(textView: TextView, dateString: String?) { val convertedDateString = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format(cal.time) val convertedTimeString = SimpleDateFormat("h a", Locale.getDefault()).format(cal.time) - val finalDisplayDateFormat = "$convertedDateString at $convertedTimeString AEST" + val finalDisplayDateFormat = "$convertedDateString at $convertedTimeString" textView.text = finalDisplayDateFormat } } diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt index 744024d..a54218c 100644 --- a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt @@ -16,6 +16,7 @@ import android.view.View.GONE import android.view.View.VISIBLE import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent +import androidx.constraintlayout.solver.GoalRow import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.fragment.app.viewModels @@ -34,6 +35,7 @@ import au.gov.health.covidsafe.notifications.NotificationBuilder import au.gov.health.covidsafe.preference.Preference import au.gov.health.covidsafe.talkback.setHeading import au.gov.health.covidsafe.ui.base.BaseFragment +import au.gov.health.covidsafe.ui.onboarding.OnboardingActivity import au.gov.health.covidsafe.utils.AnimationUtils.slideAnimation import au.gov.health.covidsafe.utils.NetworkConnectionCheck import au.gov.health.covidsafe.utils.SlideDirection @@ -67,6 +69,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ private var mIsBroadcastListenerRegistered = false private var counter: Int = 0 + private var jwtExpired: Boolean = false private var checkIsInternetConnected = false private var isAppWithLatestVersion = false @@ -95,8 +98,8 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ initializeDebugTestActivity() initializeNoNetworkError() initializeRefreshButton() - initializePullToRefresh() + initialiseReRegistration() NetworkConnectionCheck.addNetworkChangedListener(requireContext(), this) } @@ -119,6 +122,14 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ } } + private fun initialiseReRegistration() { + registration_layout.setOnClickListener { + Preference.putIsOnBoarded(requireContext(), false) + Preference.putIsReRegister(requireContext(), true) + startActivity(Intent(requireContext(), OnboardingActivity::class.java)) + } + } + private fun initiateFetchingCaseNumbers() { lifecycleScope.launch { homeFragmentViewModel.fetchGetCaseStatistics(lifecycle) @@ -127,6 +138,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ private fun initializeObservers() { (activity as HomeActivity?)?.run { + isJWTCorrupted.observe(this@HomeFragment, isJwtExpired) isAppUpdateAvailableLiveData.observe(this@HomeFragment, latestAppAvailable) isWindowFocusChangeLiveData.observe(this@HomeFragment, refreshUiObserver) } @@ -166,6 +178,10 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ } } + private val isJwtExpired = Observer { expired -> + jwtExpired = expired + } + override fun onResume() { super.onResume() @@ -337,12 +353,12 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ lifecycleScope.launch(Dispatchers.Main) { CentralLog.d(TAG, "refreshSetupCompleteOrIncompleteUi") context?.let { - val isAllPermissionsEnabled = it.allPermissionsEnabled() + val isAllPermissionsEnabled = it.allPermissionsEnabled() && !jwtExpired if (!isAllPermissionsEnabled) { NotificationBuilder.clearPossibleIssueNotificationCheck() + updateJwtExpiredHeader() } val isDataUploadedInPast14Days = isDataUploadedInPast14Days(it) - updateSetupCompleteStatus(isAllPermissionsEnabled) updateSetupCompleteHeaderTitle1(it, isAllPermissionsEnabled, isDataUploadedInPast14Days) updateSetupCompleteHeaderTitle2(isAllPermissionsEnabled) @@ -379,6 +395,16 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ } } + private fun updateJwtExpiredHeader() { + if (jwtExpired) { + permissions_card_subtitle.visibility = GONE + registration_layout.visibility = VISIBLE + } else { + permissions_card_subtitle.visibility = VISIBLE + registration_layout.visibility = GONE + } + } + private fun showLastDataUploadedInfo(context: Context, isDataUploadedInPast14Days: Boolean) { if (isDataUploadedInPast14Days) { data_last_uploaded_layout.visibility = VISIBLE @@ -430,7 +456,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ private fun updateBlueToothStatus() { requireContext().isBlueToothEnabled()?.let { - if (!it) { + if (!it && !jwtExpired) { bluetooth_card_view_layout.visibility = VISIBLE bluetooth_card_view.render(formatBlueToothTitle(it), it) } else { @@ -443,7 +469,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ private fun updateBatteryOptimizationStatus() { requireContext().isBatteryOptimizationDisabled()?.let { - if (!it) { + if (!it && !jwtExpired) { battery_card_view_layout.visibility = VISIBLE battery_card_view.render( formatNonBatteryOptimizationTitle(!it), @@ -462,7 +488,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ requireContext().isLocationPermissionAllowed()?.let { val locationWorking = it && requireContext().isLocationEnabledOnDevice() val locationOffPrompts = getString(R.string.home_set_location_why) - if (!locationWorking) { + if (!locationWorking && !jwtExpired) { location_card_view_layout.visibility = VISIBLE location_card_view.render(formatLocationTitle(locationWorking), locationWorking, locationOffPrompts) } else { diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragmentViewModel.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragmentViewModel.kt index a19a783..dff0518 100644 --- a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragmentViewModel.kt +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragmentViewModel.kt @@ -1,13 +1,9 @@ package au.gov.health.covidsafe.ui.home -import android.Manifest import android.app.Application import android.content.Context import androidx.lifecycle.* import au.gov.health.covidsafe.BuildConfig -import au.gov.health.covidsafe.R -import au.gov.health.covidsafe.extensions.LOCATION -import au.gov.health.covidsafe.extensions.askForLocationPermission import au.gov.health.covidsafe.factory.RetrofitServiceGenerator import au.gov.health.covidsafe.interactor.usecase.GetCaseStatisticsUseCase import au.gov.health.covidsafe.logging.CentralLog @@ -18,8 +14,6 @@ import au.gov.health.covidsafe.preference.Preference import com.google.gson.Gson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import pub.devrel.easypermissions.EasyPermissions -import pub.devrel.easypermissions.PermissionRequest private const val TAG = "HomeFragmentViewModel" diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt index c80536d..922c593 100644 --- a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt @@ -8,6 +8,7 @@ import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity +import androidx.navigation.fragment.NavHostFragment import au.gov.health.covidsafe.ui.base.HasBlockingState import au.gov.health.covidsafe.preference.Preference import au.gov.health.covidsafe.R @@ -33,6 +34,16 @@ class OnboardingActivity : FragmentActivity(), HasBlockingState, PagerContainer if (isUiBlocked) { loadingProgressBarFrame?.isVisible = true } + + val myNavHostFragment: NavHostFragment = fragment_nav_host as NavHostFragment + val inflater = myNavHostFragment.navController.navInflater + if (Preference.isReRegister(this)) { + val graph = inflater.inflate(R.navigation.nav_re_register) + myNavHostFragment.navController.graph = graph + } else { + val graph = inflater.inflate(R.navigation.nav_onboarding) + myNavHostFragment.navController.graph = graph + } } override fun onAttachFragment(fragment: Fragment) { diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt index ed0b2ea..64d764e 100644 --- a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt @@ -10,6 +10,7 @@ import android.view.accessibility.AccessibilityEvent import au.gov.health.covidsafe.HomeActivity import au.gov.health.covidsafe.R import au.gov.health.covidsafe.links.LinkBuilder +import au.gov.health.covidsafe.preference.Preference import au.gov.health.covidsafe.talkback.setHeading import au.gov.health.covidsafe.ui.base.PagerChildFragment import au.gov.health.covidsafe.ui.base.UploadButtonLayout @@ -28,6 +29,12 @@ class PermissionSuccessFragment : PagerChildFragment() { permission_success_headline.setHeading() permission_success_headline.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED) + if (Preference.isReRegister(requireContext())) { + permission_success_headline.text = requireContext().getString(R.string.jwt_success) + } else { + permission_success_headline.text = requireContext().getString(R.string.permission_success_headline) + } + permission_success_content.text = LinkBuilder.getHowPermissionSuccessContent(requireContext()) permission_success_content.movementMethod = LinkMovementMethod.getInstance() diff --git a/app/src/main/res/drawable/ic_vector.xml b/app/src/main/res/drawable/ic_vector.xml new file mode 100644 index 0000000..3a3e758 --- /dev/null +++ b/app/src/main/res/drawable/ic_vector.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml index f0b06bc..10716da 100644 --- a/app/src/main/res/layout/activity_onboarding.xml +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -37,8 +37,7 @@ android:layout_height="0dp" android:layout_width="match_parent" android:layout_weight="1" - app:defaultNavHost="true" - app:navGraph="@navigation/nav_onboarding" /> + app:defaultNavHost="true"/> +