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