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 }