blob: 4a4f2e9710dd47235b936f69333e3e5768c38590 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.wallet.controller;
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
import android.content.Context;
import android.database.ContentObserver;
import android.provider.Settings;
import android.service.quickaccesswallet.GetWalletCardsRequest;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.service.quickaccesswallet.QuickAccessWalletClientImpl;
import android.util.Log;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.SystemClock;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
/**
* Controller to handle communication between SystemUI and Quick Access Wallet Client.
*/
@SysUISingleton
public class QuickAccessWalletController {
/**
* Event for the wallet status change, e.g. the default payment app change and the wallet
* preference change.
*/
public enum WalletChangeEvent {
DEFAULT_PAYMENT_APP_CHANGE,
WALLET_PREFERENCE_CHANGE,
}
private static final String TAG = "QAWController";
private static final long RECREATION_TIME_WINDOW = TimeUnit.MINUTES.toMillis(10L);
private final Context mContext;
private final Executor mExecutor;
private final SecureSettings mSecureSettings;
private final SystemClock mClock;
private QuickAccessWalletClient mQuickAccessWalletClient;
private ContentObserver mWalletPreferenceObserver;
private ContentObserver mDefaultPaymentAppObserver;
private int mWalletPreferenceChangeEvents = 0;
private int mDefaultPaymentAppChangeEvents = 0;
private boolean mWalletEnabled = false;
private long mQawClientCreatedTimeMillis;
@Inject
public QuickAccessWalletController(
Context context,
@Main Executor executor,
SecureSettings secureSettings,
QuickAccessWalletClient quickAccessWalletClient,
SystemClock clock) {
mContext = context;
mExecutor = executor;
mSecureSettings = secureSettings;
mQuickAccessWalletClient = quickAccessWalletClient;
mClock = clock;
mQawClientCreatedTimeMillis = mClock.elapsedRealtime();
}
/**
* Returns true if the Quick Access Wallet service & feature is available.
*/
public boolean isWalletEnabled() {
return mWalletEnabled;
}
/**
* Returns the current instance of {@link QuickAccessWalletClient} in the controller.
*/
public QuickAccessWalletClient getWalletClient() {
return mQuickAccessWalletClient;
}
/**
* Setup the wallet change observers per {@link WalletChangeEvent}
*
* @param cardsRetriever a callback that retrieves the wallet cards
* @param events {@link WalletChangeEvent} need to be handled.
*/
public void setupWalletChangeObservers(
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever,
WalletChangeEvent... events) {
for (WalletChangeEvent event : events) {
if (event == WALLET_PREFERENCE_CHANGE) {
setupWalletPreferenceObserver();
} else if (event == DEFAULT_PAYMENT_APP_CHANGE) {
setupDefaultPaymentAppObserver(cardsRetriever);
}
}
}
/**
* Unregister wallet change observers per {@link WalletChangeEvent} if needed.
*
*/
public void unregisterWalletChangeObservers(WalletChangeEvent... events) {
for (WalletChangeEvent event : events) {
if (event == WALLET_PREFERENCE_CHANGE && mWalletPreferenceObserver != null) {
mWalletPreferenceChangeEvents--;
if (mWalletPreferenceChangeEvents == 0) {
mSecureSettings.unregisterContentObserver(mWalletPreferenceObserver);
}
} else if (event == DEFAULT_PAYMENT_APP_CHANGE && mDefaultPaymentAppObserver != null) {
mDefaultPaymentAppChangeEvents--;
if (mDefaultPaymentAppChangeEvents == 0) {
mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver);
}
}
}
}
/**
* Update the "show wallet" preference.
*/
public void updateWalletPreference() {
mWalletEnabled = mQuickAccessWalletClient.isWalletServiceAvailable()
&& mQuickAccessWalletClient.isWalletFeatureAvailable()
&& mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked();
}
/**
* Query the wallet cards from {@link QuickAccessWalletClient}.
*
* @param cardsRetriever a callback to retrieve wallet cards.
*/
public void queryWalletCards(
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
if (mClock.elapsedRealtime() - mQawClientCreatedTimeMillis
> RECREATION_TIME_WINDOW) {
Log.i(TAG, "Re-creating the QAW client to avoid stale.");
reCreateWalletClient();
}
if (!mQuickAccessWalletClient.isWalletFeatureAvailable()) {
Log.d(TAG, "QuickAccessWallet feature is not available.");
return;
}
int cardWidth =
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
int cardHeight =
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height);
int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
GetWalletCardsRequest request =
new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 1);
mQuickAccessWalletClient.getWalletCards(mExecutor, request, cardsRetriever);
}
/**
* Re-create the {@link QuickAccessWalletClient} of the controller.
*/
public void reCreateWalletClient() {
mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
mQawClientCreatedTimeMillis = mClock.elapsedRealtime();
}
private void setupDefaultPaymentAppObserver(
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
if (mDefaultPaymentAppObserver == null) {
mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean selfChange) {
mExecutor.execute(() -> {
reCreateWalletClient();
updateWalletPreference();
queryWalletCards(cardsRetriever);
});
}
};
mSecureSettings.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT),
false /* notifyForDescendants */,
mDefaultPaymentAppObserver);
}
mDefaultPaymentAppChangeEvents++;
}
private void setupWalletPreferenceObserver() {
if (mWalletPreferenceObserver == null) {
mWalletPreferenceObserver = new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean selfChange) {
mExecutor.execute(() -> {
updateWalletPreference();
});
}
};
mSecureSettings.registerContentObserver(
Settings.Secure.getUriFor(QuickAccessWalletClientImpl.SETTING_KEY),
false /* notifyForDescendants */,
mWalletPreferenceObserver);
}
mWalletPreferenceChangeEvents++;
}
}