1 package com.android.systemui.wallet.controller 2 3 import android.content.Intent 4 import android.os.IBinder 5 import android.util.Log 6 import androidx.annotation.VisibleForTesting 7 import androidx.lifecycle.LifecycleService 8 import androidx.lifecycle.lifecycleScope 9 import com.android.systemui.flags.FeatureFlags 10 import com.android.systemui.flags.Flags 11 import javax.inject.Inject 12 import kotlinx.coroutines.CoroutineScope 13 import kotlinx.coroutines.launch 14 15 /** 16 * Serves as an intermediary between QuickAccessWalletService and ContextualCardManager (in PCC). 17 * When QuickAccessWalletService has a list of store locations, WalletContextualLocationsService 18 * will send them to ContextualCardManager. When the user enters a store location, this Service 19 * class will be notified, and WalletContextualSuggestionsController will be updated. 20 */ 21 class WalletContextualLocationsService 22 @Inject 23 constructor( 24 private val controller: WalletContextualSuggestionsController, 25 private val featureFlags: FeatureFlags, 26 ) : LifecycleService() { 27 private var listener: IWalletCardsUpdatedListener? = null 28 private var scope: CoroutineScope = this.lifecycleScope 29 30 @VisibleForTesting 31 constructor( 32 controller: WalletContextualSuggestionsController, 33 featureFlags: FeatureFlags, 34 scope: CoroutineScope, 35 ) : this(controller, featureFlags) { 36 this.scope = scope 37 } 38 39 override fun onBind(intent: Intent): IBinder { 40 super.onBind(intent) 41 scope.launch { 42 controller.allWalletCards.collect { cards -> 43 val cardsSize = cards.size 44 Log.i(TAG, "Number of cards registered $cardsSize") 45 listener?.registerNewWalletCards(cards) 46 } 47 } 48 return binder 49 } 50 51 override fun onDestroy() { 52 super.onDestroy() 53 listener = null 54 } 55 56 @VisibleForTesting 57 fun addWalletCardsUpdatedListenerInternal(listener: IWalletCardsUpdatedListener) { 58 if (!featureFlags.isEnabled(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)) { 59 return 60 } 61 this.listener = listener // Currently, only one listener at a time is supported 62 // Sends WalletCard objects from QuickAccessWalletService to the listener 63 val cards = controller.allWalletCards.value 64 if (!cards.isEmpty()) { 65 val cardsSize = cards.size 66 Log.i(TAG, "Number of cards registered $cardsSize") 67 listener.registerNewWalletCards(cards) 68 } 69 } 70 71 @VisibleForTesting 72 fun onWalletContextualLocationsStateUpdatedInternal(storeLocations: List<String>) { 73 if (!featureFlags.isEnabled(Flags.ENABLE_WALLET_CONTEXTUAL_LOYALTY_CARDS)) { 74 return 75 } 76 Log.i(TAG, "Entered store $storeLocations") 77 controller.setSuggestionCardIds(storeLocations.toSet()) 78 } 79 80 private val binder: IWalletContextualLocationsService.Stub 81 = object : IWalletContextualLocationsService.Stub() { 82 override fun addWalletCardsUpdatedListener(listener: IWalletCardsUpdatedListener) { 83 addWalletCardsUpdatedListenerInternal(listener) 84 } 85 override fun onWalletContextualLocationsStateUpdated(storeLocations: List<String>) { 86 onWalletContextualLocationsStateUpdatedInternal(storeLocations) 87 } 88 } 89 90 companion object { 91 private const val TAG = "WalletContextualLocationsService" 92 } 93 }