Skip to content

Commit d486f79

Browse files
authored
Merge pull request #1694 from Infomaniak/Use-new-UpdateManager
Use new Update Manager
2 parents 0b8e689 + 31695bf commit d486f79

File tree

10 files changed

+93
-99
lines changed

10 files changed

+93
-99
lines changed

app/src/main/java/com/infomaniak/mail/data/LocalSettings.kt

-9
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import com.infomaniak.lib.core.utils.SentryLog
2727
import com.infomaniak.lib.core.utils.SharedValues
2828
import com.infomaniak.lib.core.utils.sharedValue
2929
import com.infomaniak.lib.core.utils.transaction
30-
import com.infomaniak.lib.stores.StoreUtils.APP_UPDATE_TAG
3130
import com.infomaniak.mail.MatomoMail.ACTION_ARCHIVE_NAME
3231
import com.infomaniak.mail.MatomoMail.ACTION_DELETE_NAME
3332
import com.infomaniak.mail.MatomoMail.ACTION_FAVORITE_NAME
@@ -49,8 +48,6 @@ class LocalSettings private constructor(context: Context) : SharedValues {
4948
var askEmailAcknowledgement by sharedValue("askEmailAcknowledgmentKey", false)
5049
var hasAlreadyEnabledNotifications by sharedValue("hasAlreadyEnabledNotificationsKey", false)
5150
var isAppLocked by sharedValue("isAppLockedKey", false)
52-
var isUserWantingUpdates by sharedValue("isUserWantingUpdatesKey", true)
53-
var hasAppUpdateDownloaded by sharedValue("hasAppUpdateDownloaded", false)
5451
var aiEngine by sharedValue("aiEngineKey", AiEngine.FALCON)
5552
var threadDensity by sharedValue("threadDensityKey", ThreadDensity.LARGE)
5653
var theme by sharedValue("themeKey", if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) Theme.LIGHT else Theme.SYSTEM)
@@ -71,12 +68,6 @@ class LocalSettings private constructor(context: Context) : SharedValues {
7168

7269
fun removeSettings() = sharedPreferences.transaction { clear() }
7370

74-
fun resetUpdateSettings() {
75-
SentryLog.d(APP_UPDATE_TAG, "Reset update settings")
76-
isUserWantingUpdates = false // This avoid the user being instantly reprompted to download update
77-
hasAppUpdateDownloaded = false
78-
}
79-
8071
fun getSwipeAction(@StringRes nameRes: Int): SwipeAction = when (nameRes) {
8172
R.string.settingsSwipeRight -> swipeRight
8273
R.string.settingsSwipeLeft -> swipeLeft
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Infomaniak Mail - Android
3+
* Copyright (C) 2024 Infomaniak Network SA
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.infomaniak.mail.di
19+
20+
import androidx.fragment.app.FragmentActivity
21+
import com.infomaniak.lib.stores.InAppUpdateManager
22+
import com.infomaniak.mail.BuildConfig
23+
import com.infomaniak.mail.MatomoMail.DISCOVER_LATER
24+
import com.infomaniak.mail.MatomoMail.DISCOVER_NOW
25+
import com.infomaniak.mail.MatomoMail.trackInAppUpdateEvent
26+
import com.infomaniak.mail.ui.main.SnackbarManager
27+
import dagger.Module
28+
import dagger.Provides
29+
import dagger.hilt.InstallIn
30+
import dagger.hilt.android.components.ActivityComponent
31+
import dagger.hilt.android.scopes.ActivityScoped
32+
import io.sentry.Sentry
33+
import com.infomaniak.lib.core.R as RCore
34+
35+
@Module
36+
@InstallIn(ActivityComponent::class)
37+
object ActivityModule {
38+
39+
@ActivityScoped
40+
@Provides
41+
fun provideInAppUpdateManager(activity: FragmentActivity, snackbarManager: SnackbarManager) = InAppUpdateManager(
42+
activity = activity,
43+
appId = BuildConfig.APPLICATION_ID,
44+
versionCode = BuildConfig.VERSION_CODE,
45+
onUserChoice = { isWantingUpdate -> activity.trackInAppUpdateEvent(if (isWantingUpdate) DISCOVER_NOW else DISCOVER_LATER) },
46+
onInstallStart = { activity.trackInAppUpdateEvent("installUpdate") },
47+
onInstallFailure = {
48+
Sentry.captureException(it)
49+
snackbarManager.setValue(activity.getString(RCore.string.errorUpdateInstall))
50+
},
51+
)
52+
}

app/src/main/java/com/infomaniak/mail/di/ApplicationModule.kt

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.app.Application
2121
import android.content.Context
2222
import androidx.core.app.NotificationManagerCompat
2323
import androidx.work.WorkManager
24+
import com.infomaniak.lib.stores.StoresLocalSettings
2425
import com.infomaniak.mail.MainApplication
2526
import com.infomaniak.mail.data.LocalSettings
2627
import dagger.Module
@@ -61,4 +62,8 @@ object ApplicationModule {
6162
@Provides
6263
@Singleton
6364
fun providesLocalSettings(appContext: Context): LocalSettings = LocalSettings.getInstance(appContext)
65+
66+
@Provides
67+
@Singleton
68+
fun providesStoresLocalSettings(appContext: Context): StoresLocalSettings = StoresLocalSettings.getInstance(appContext)
6469
}

app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt

+13-39
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import android.view.ViewGroup
2626
import android.webkit.WebView
2727
import androidx.activity.addCallback
2828
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
29-
import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult
3029
import androidx.activity.viewModels
3130
import androidx.annotation.FloatRange
3231
import androidx.core.view.isVisible
@@ -40,24 +39,18 @@ import androidx.navigation.fragment.NavHostFragment
4039
import androidx.work.Data
4140
import com.infomaniak.lib.core.MatomoCore.TrackerAction
4241
import com.infomaniak.lib.core.networking.LiveDataNetworkStatus
43-
import com.infomaniak.lib.core.utils.SentryLog
42+
import com.infomaniak.lib.core.utils.*
4443
import com.infomaniak.lib.core.utils.Utils
4544
import com.infomaniak.lib.core.utils.Utils.toEnumOrThrow
4645
import com.infomaniak.lib.core.utils.UtilsUi.openUrl
47-
import com.infomaniak.lib.core.utils.hasPermissions
48-
import com.infomaniak.lib.core.utils.year
49-
import com.infomaniak.lib.stores.StoreUtils.checkUpdateIsAvailable
50-
import com.infomaniak.lib.stores.StoreUtils.initAppUpdateManager
46+
import com.infomaniak.lib.stores.InAppUpdateManager
47+
import com.infomaniak.lib.stores.StoreUtils
5148
import com.infomaniak.lib.stores.StoreUtils.launchInAppReview
52-
import com.infomaniak.lib.stores.StoreUtils.unregisterAppUpdateListener
5349
import com.infomaniak.mail.BuildConfig
54-
import com.infomaniak.mail.MatomoMail.DISCOVER_LATER
55-
import com.infomaniak.mail.MatomoMail.DISCOVER_NOW
5650
import com.infomaniak.mail.MatomoMail.trackAppReviewEvent
5751
import com.infomaniak.mail.MatomoMail.trackDestination
5852
import com.infomaniak.mail.MatomoMail.trackEasterEggEvent
5953
import com.infomaniak.mail.MatomoMail.trackEvent
60-
import com.infomaniak.mail.MatomoMail.trackInAppUpdateEvent
6154
import com.infomaniak.mail.MatomoMail.trackMenuDrawerEvent
6255
import com.infomaniak.mail.R
6356
import com.infomaniak.mail.data.LocalSettings
@@ -127,12 +120,6 @@ class MainActivity : BaseActivity() {
127120
}
128121
}
129122

130-
private val inAppUpdateResultLauncher = registerForActivityResult(StartIntentSenderForResult()) { result ->
131-
val isUserWantingUpdates = result.resultCode == RESULT_OK
132-
localSettings.isUserWantingUpdates = isUserWantingUpdates
133-
trackInAppUpdateEvent(if (isUserWantingUpdates) DISCOVER_NOW else DISCOVER_LATER)
134-
}
135-
136123
private val currentFragment
137124
get() = supportFragmentManager
138125
.findFragmentById(R.id.mainHostFragment)
@@ -157,6 +144,9 @@ class MainActivity : BaseActivity() {
157144
@Inject
158145
lateinit var snackbarManager: SnackbarManager
159146

147+
@Inject
148+
lateinit var inAppUpdateManager: InAppUpdateManager
149+
160150
private val drawerListener = object : DrawerLayout.DrawerListener {
161151

162152
var hasDragged = false
@@ -348,14 +338,12 @@ class MainActivity : BaseActivity() {
348338
appReviewLaunches--
349339
}
350340

351-
showUpdateAvailable()
352341
showSyncDiscovery()
353342
}
354343

355344
override fun onResume() {
356345
super.onResume()
357346
playServicesUtils.checkPlayServices(this)
358-
mainViewModel.checkAppUpdateStatus()
359347
if (binding.drawerLayout.isOpen) colorSystemBarsWithMenuDrawer(UiUtils.FULLY_SLID)
360348
}
361349

@@ -388,7 +376,6 @@ class MainActivity : BaseActivity() {
388376

389377
override fun onStop() {
390378
descriptionDialog.resetLoadingAndDismiss()
391-
unregisterAppUpdateListener()
392379
super.onStop()
393380
}
394381

@@ -467,27 +454,14 @@ class MainActivity : BaseActivity() {
467454
}
468455
}
469456

470-
private fun initAppUpdateManager() {
471-
initAppUpdateManager(
472-
context = this,
473-
onUpdateDownloaded = { mainViewModel.toggleAppUpdateStatus(isUpdateDownloaded = true) },
474-
onUpdateInstalled = {
475-
Sentry.captureMessage("InstallStateUpdateListener called ’state == INSTALLED’", SentryLevel.DEBUG)
476-
mainViewModel.toggleAppUpdateStatus(isUpdateDownloaded = false)
477-
},
478-
)
479-
}
457+
private fun initAppUpdateManager() = with(inAppUpdateManager) {
458+
onFDroidResult = { updateIsAvailable ->
459+
if (updateIsAvailable) navController.navigate(R.id.updateAvailableBottomSheetDialog)
460+
}
480461

481-
private fun showUpdateAvailable() = with(localSettings) {
482-
if (isUserWantingUpdates || (appLaunches != 0 && appLaunches % 10 == 0)) {
483-
checkUpdateIsAvailable(
484-
appId = BuildConfig.APPLICATION_ID,
485-
versionCode = BuildConfig.VERSION_CODE,
486-
inAppResultLauncher = inAppUpdateResultLauncher,
487-
onFDroidResult = { updateIsAvailable ->
488-
if (updateIsAvailable) navController.navigate(R.id.updateAvailableBottomSheetDialog)
489-
},
490-
)
462+
onInAppUpdateUiChange = { isUpdateDownloaded ->
463+
SentryLog.d(StoreUtils.APP_UPDATE_TAG, "Must display update button : $isUpdateDownloaded")
464+
mainViewModel.canInstallUpdate.value = isUpdateDownloaded
491465
}
492466
}
493467

app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt

-17
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import com.infomaniak.lib.core.utils.ApiErrorCode.Companion.translateError
2424
import com.infomaniak.lib.core.utils.DownloadManagerUtils
2525
import com.infomaniak.lib.core.utils.SentryLog
2626
import com.infomaniak.lib.core.utils.SingleLiveEvent
27-
import com.infomaniak.lib.stores.StoreUtils
28-
import com.infomaniak.lib.stores.StoreUtils.APP_UPDATE_TAG
2927
import com.infomaniak.mail.MatomoMail.trackMultiSelectionEvent
3028
import com.infomaniak.mail.R
3129
import com.infomaniak.mail.data.LocalSettings
@@ -1026,21 +1024,6 @@ class MainViewModel @Inject constructor(
10261024
snackbarManager.postValue(context.getString(snackbarTitleRes))
10271025
}
10281026

1029-
fun checkAppUpdateStatus() {
1030-
SentryLog.d(
1031-
tag = APP_UPDATE_TAG,
1032-
msg = "Setting canInstallUpdate value to ${localSettings.hasAppUpdateDownloaded} in checkAppUpdateStatus",
1033-
)
1034-
canInstallUpdate.value = localSettings.hasAppUpdateDownloaded
1035-
StoreUtils.checkStalledUpdate()
1036-
}
1037-
1038-
fun toggleAppUpdateStatus(isUpdateDownloaded: Boolean) {
1039-
SentryLog.d(APP_UPDATE_TAG, "Setting canInstallUpdate value to $isUpdateDownloaded in toggleAppUpdateStatus")
1040-
canInstallUpdate.value = isUpdateDownloaded
1041-
localSettings.hasAppUpdateDownloaded = isUpdateDownloaded
1042-
}
1043-
10441027
companion object {
10451028
private val TAG: String = MainViewModel::class.java.simpleName
10461029
private val DEFAULT_SELECTED_FOLDER = FolderRole.INBOX

app/src/main/java/com/infomaniak/mail/ui/bottomSheetDialogs/UpdateAvailableBottomSheetDialog.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import android.view.View
2222
import com.infomaniak.lib.core.utils.context
2323
import com.infomaniak.lib.core.utils.getAppName
2424
import com.infomaniak.lib.core.utils.goToPlayStore
25+
import com.infomaniak.lib.stores.StoresLocalSettings
2526
import com.infomaniak.mail.MatomoMail.DISCOVER_LATER
2627
import com.infomaniak.mail.MatomoMail.DISCOVER_NOW
2728
import com.infomaniak.mail.MatomoMail.trackAppUpdateEvent
2829
import com.infomaniak.mail.R
29-
import com.infomaniak.mail.data.LocalSettings
3030
import dagger.hilt.android.AndroidEntryPoint
3131
import javax.inject.Inject
3232
import com.infomaniak.lib.core.R as RCore
@@ -35,7 +35,7 @@ import com.infomaniak.lib.core.R as RCore
3535
class UpdateAvailableBottomSheetDialog : InformationBottomSheetDialog() {
3636

3737
@Inject
38-
lateinit var localSettings: LocalSettings
38+
lateinit var storesLocalSettings: StoresLocalSettings
3939

4040
override fun onViewCreated(view: View, savedInstanceState: Bundle?): Unit = with(binding) {
4141
super.onViewCreated(view, savedInstanceState)
@@ -48,15 +48,15 @@ class UpdateAvailableBottomSheetDialog : InformationBottomSheetDialog() {
4848
trackAppUpdateEvent(DISCOVER_NOW)
4949
setText(RCore.string.buttonUpdate)
5050
setOnClickListener {
51-
localSettings.isUserWantingUpdates = true
51+
storesLocalSettings.isUserWantingUpdates = true
5252
requireContext().goToPlayStore()
5353
dismiss()
5454
}
5555
}
5656

5757
secondaryActionButton.setOnClickListener {
5858
trackAppUpdateEvent(DISCOVER_LATER)
59-
localSettings.isUserWantingUpdates = false
59+
storesLocalSettings.isUserWantingUpdates = false
6060
dismiss()
6161
}
6262
}

app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListFragment.kt

+9-23
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,8 @@ import com.ernestoyaquello.dragdropswiperecyclerview.listener.OnListScrollListen
4646
import com.ernestoyaquello.dragdropswiperecyclerview.listener.OnListScrollListener.ScrollState
4747
import com.infomaniak.lib.core.MatomoCore.TrackerAction
4848
import com.infomaniak.lib.core.utils.*
49-
import com.infomaniak.lib.stores.StoreUtils
50-
import com.infomaniak.lib.stores.StoreUtils.APP_UPDATE_TAG
49+
import com.infomaniak.lib.stores.InAppUpdateManager
5150
import com.infomaniak.mail.MatomoMail.trackEvent
52-
import com.infomaniak.mail.MatomoMail.trackInAppUpdateEvent
5351
import com.infomaniak.mail.MatomoMail.trackMenuDrawerEvent
5452
import com.infomaniak.mail.MatomoMail.trackMultiSelectionEvent
5553
import com.infomaniak.mail.MatomoMail.trackNewMessageEvent
@@ -103,6 +101,10 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen
103101
private var lastUpdatedDate: Date? = null
104102
private var previousCustomFolderId: String? = null
105103

104+
private val showLoadingTimer: CountDownTimer by lazy { Utils.createRefreshTimer(onTimerFinish = ::showRefreshLayout) }
105+
106+
private var canRefreshThreads = false
107+
106108
@Inject
107109
lateinit var localSettings: LocalSettings
108110

@@ -115,16 +117,15 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen
115117
@Inject
116118
lateinit var playServicesUtils: PlayServicesUtils
117119

118-
private val showLoadingTimer: CountDownTimer by lazy { Utils.createRefreshTimer(onTimerFinish = ::showRefreshLayout) }
119-
120-
private var canRefreshThreads = false
121-
122120
@Inject
123121
lateinit var descriptionDialog: DescriptionAlertDialog
124122

125123
@Inject
126124
lateinit var snackbarManager: SnackbarManager
127125

126+
@Inject
127+
lateinit var inAppUpdateManager: InAppUpdateManager
128+
128129
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
129130
return FragmentThreadListBinding.inflate(inflater, container, false).also { _binding = it }.root
130131
}
@@ -625,23 +626,8 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen
625626

626627
private fun observeUpdateInstall() = with(binding) {
627628
mainViewModel.canInstallUpdate.observe(viewLifecycleOwner) { isUpdateDownloaded ->
628-
SentryLog.d(APP_UPDATE_TAG, "Must display update button : $isUpdateDownloaded")
629629
installUpdateGroup.isVisible = isUpdateDownloaded
630-
installUpdate.setOnClickListener {
631-
SentryLog.d(APP_UPDATE_TAG, "Install downloaded Update from button")
632-
context.trackInAppUpdateEvent("installUpdate")
633-
mainViewModel.canInstallUpdate.value = false
634-
localSettings.hasAppUpdateDownloaded = false
635-
636-
StoreUtils.installDownloadedUpdate(
637-
onFailure = {
638-
Sentry.captureException(it)
639-
localSettings.resetUpdateSettings()
640-
641-
snackbarManager.setValue(getString(RCore.string.errorUpdateInstall))
642-
},
643-
)
644-
}
630+
installUpdate.setOnClickListener { inAppUpdateManager.installDownloadedUpdate() }
645631
}
646632
}
647633

app/src/main/java/com/infomaniak/mail/utils/LogoutUser.kt

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import androidx.work.WorkManager
2323
import com.infomaniak.lib.core.models.user.User
2424
import com.infomaniak.lib.core.networking.HttpClient
2525
import com.infomaniak.lib.core.utils.SentryLog
26+
import com.infomaniak.lib.stores.StoresLocalSettings
2627
import com.infomaniak.mail.data.LocalSettings
2728
import com.infomaniak.mail.data.cache.RealmDatabase
2829
import com.infomaniak.mail.data.cache.appSettings.AppSettingsController
@@ -42,6 +43,7 @@ class LogoutUser @Inject constructor(
4243
private val localSettings: LocalSettings,
4344
private val mailboxController: MailboxController,
4445
private val playServicesUtils: PlayServicesUtils,
46+
private val storesLocalSettings: StoresLocalSettings,
4547
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
4648
) {
4749

@@ -81,6 +83,7 @@ class LogoutUser @Inject constructor(
8183
private fun resetSettings() {
8284
AppSettingsController.removeAppSettings()
8385
localSettings.removeSettings()
86+
storesLocalSettings.removeSettings()
8487
with(WorkManager.getInstance(appContext)) {
8588
cancelAllWork()
8689
pruneWork()

0 commit comments

Comments
 (0)