Loading packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java +5 −1 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ public interface QSTile { public SlashState slash; public boolean handlesLongClick = true; public boolean showRippleEffect = true; public Drawable sideViewDrawable; public boolean copyTo(State other) { if (other == null) throw new IllegalArgumentException(); Loading @@ -163,7 +164,8 @@ public interface QSTile { || !Objects.equals(other.dualTarget, dualTarget) || !Objects.equals(other.slash, slash) || !Objects.equals(other.handlesLongClick, handlesLongClick) || !Objects.equals(other.showRippleEffect, showRippleEffect); || !Objects.equals(other.showRippleEffect, showRippleEffect) || !Objects.equals(other.sideViewDrawable, sideViewDrawable); other.icon = icon; other.iconSupplier = iconSupplier; other.label = label; Loading @@ -179,6 +181,7 @@ public interface QSTile { other.slash = slash != null ? slash.copy() : null; other.handlesLongClick = handlesLongClick; other.showRippleEffect = showRippleEffect; other.sideViewDrawable = sideViewDrawable; return changed; } Loading @@ -204,6 +207,7 @@ public interface QSTile { sb.append(",isTransient=").append(isTransient); sb.append(",state=").append(state); sb.append(",slash=\"").append(slash).append("\""); sb.append(",sideViewDrawable").append(sideViewDrawable); return sb.append(']'); } Loading packages/SystemUI/res/layout/qs_tile_label.xml +2 −1 Original line number Diff line number Diff line Loading @@ -16,8 +16,9 @@ --> <com.android.systemui.qs.tileimpl.ButtonRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clipChildren="false" android:clipToPadding="false" android:paddingTop="12dp"> Loading packages/SystemUI/res/values/dimens.xml +2 −0 Original line number Diff line number Diff line Loading @@ -1437,4 +1437,6 @@ <dimen name="min_wallet_empty_height">208dp</dimen> <dimen name="wallet_card_border_width">1dp</dimen> <dimen name="wallet_empty_state_corner_radius">24dp</dimen> <dimen name="wallet_tile_card_view_height">32dp</dimen> <dimen name="wallet_tile_card_view_width">50dp</dimen> </resources> packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt +28 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.RippleDrawable import android.service.quicksettings.Tile.STATE_ACTIVE import android.view.Gravity import android.view.View import android.widget.ImageView import android.widget.LinearLayout import android.widget.RelativeLayout import com.android.systemui.R Loading @@ -41,6 +43,7 @@ open class QSTileViewHorizontal( private var paintColor = Color.WHITE private var paintAnimator: ValueAnimator? = null private var labelAnimator: ValueAnimator? = null private var mSideView: ImageView = ImageView(mContext) override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE init { Loading @@ -56,6 +59,14 @@ open class QSTileViewHorizontal( val iconSize = context.resources.getDimensionPixelSize(R.dimen.qs_icon_size) addView(mIcon, 0, LayoutParams(iconSize, iconSize)) mSideView.visibility = View.GONE addView( mSideView, -1, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply { gravity = Gravity.CENTER_VERTICAL }) mColorLabelActive = ColorStateList.valueOf(getColorForState(getContext(), STATE_ACTIVE)) changeLabelColor(getLabelColor(mState)) // Matches the default state of the tile } Loading Loading @@ -128,6 +139,7 @@ open class QSTileViewHorizontal( } paintColor = newColor } loadSideViewDrawableIfNecessary(state) } private fun animateBackground(newBackgroundColor: Int) { Loading Loading @@ -180,5 +192,21 @@ open class QSTileViewHorizontal( labelAnimator?.cancel()?.also { labelAnimator = null } } private fun loadSideViewDrawableIfNecessary(state: QSTile.State) { if (state.sideViewDrawable != null) { (mSideView.layoutParams as MarginLayoutParams).apply { marginStart = context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin) } mSideView.setImageDrawable(state.sideViewDrawable) mSideView.visibility = View.VISIBLE mSideView.adjustViewBounds = true mSideView.scaleType = ImageView.ScaleType.FIT_CENTER } else { mSideView.setImageDrawable(null) mSideView.visibility = GONE } } override fun handleExpand(dualTarget: Boolean) {} } No newline at end of file packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +65 −0 Original line number Diff line number Diff line Loading @@ -20,11 +20,20 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.WalletCard; import android.service.quicksettings.Tile; import android.util.Log; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; Loading @@ -40,20 +49,29 @@ import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.settings.SecureSettings; import java.util.List; import java.util.concurrent.Executor; import javax.inject.Inject; /** Quick settings tile: Quick access wallet **/ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { private static final String TAG = "QuickAccessWalletTile"; private static final String FEATURE_CHROME_OS = "org.chromium.arc"; private final CharSequence mLabel = mContext.getString(R.string.wallet_title); private final WalletCardRetriever mCardRetriever = new WalletCardRetriever(); // TODO(b/180959290): Re-create the QAW Client when the default NFC payment app changes. private final QuickAccessWalletClient mQuickAccessWalletClient; private final KeyguardStateController mKeyguardStateController; private final PackageManager mPackageManager; private final SecureSettings mSecureSettings; private final Executor mExecutor; private final FeatureFlags mFeatureFlags; @VisibleForTesting Drawable mCardViewDrawable; @Inject public QuickAccessWalletTile( QSHost host, Loading @@ -68,6 +86,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { KeyguardStateController keyguardStateController, PackageManager packageManager, SecureSettings secureSettings, @Background Executor executor, FeatureFlags featureFlags) { super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); Loading @@ -75,6 +94,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { mKeyguardStateController = keyguardStateController; mPackageManager = packageManager; mSecureSettings = secureSettings; mExecutor = executor; mFeatureFlags = featureFlags; } Loading @@ -86,6 +106,14 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { return state; } @Override protected void handleSetListening(boolean listening) { super.handleSetListening(listening); if (listening) { queryWalletCards(); } } @Override protected void handleClick() { mActivityStarter.postStartActivityDismissingKeyguard( Loading @@ -108,6 +136,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { } else { state.state = Tile.STATE_UNAVAILABLE; } state.sideViewDrawable = mCardViewDrawable; } @Override Loading @@ -133,4 +162,40 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { CharSequence qawLabel = mQuickAccessWalletClient.getServiceLabel(); return qawLabel == null ? mLabel : qawLabel; } private void queryWalletCards() { 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= */ 2); mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever); } private class WalletCardRetriever implements QuickAccessWalletClient.OnWalletCardsRetrievedCallback { @Override public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) { Log.i(TAG, "Successfully retrieved wallet cards."); List<WalletCard> cards = response.getWalletCards(); if (cards.isEmpty()) { Log.d(TAG, "No wallet cards exist."); mCardViewDrawable = null; refreshState(); return; } mCardViewDrawable = cards.get(0).getCardImage().loadDrawable(mContext); refreshState(); } @Override public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) { Log.w(TAG, "Error retrieve wallet cards"); mCardViewDrawable = null; refreshState(); } } } Loading
packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java +5 −1 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ public interface QSTile { public SlashState slash; public boolean handlesLongClick = true; public boolean showRippleEffect = true; public Drawable sideViewDrawable; public boolean copyTo(State other) { if (other == null) throw new IllegalArgumentException(); Loading @@ -163,7 +164,8 @@ public interface QSTile { || !Objects.equals(other.dualTarget, dualTarget) || !Objects.equals(other.slash, slash) || !Objects.equals(other.handlesLongClick, handlesLongClick) || !Objects.equals(other.showRippleEffect, showRippleEffect); || !Objects.equals(other.showRippleEffect, showRippleEffect) || !Objects.equals(other.sideViewDrawable, sideViewDrawable); other.icon = icon; other.iconSupplier = iconSupplier; other.label = label; Loading @@ -179,6 +181,7 @@ public interface QSTile { other.slash = slash != null ? slash.copy() : null; other.handlesLongClick = handlesLongClick; other.showRippleEffect = showRippleEffect; other.sideViewDrawable = sideViewDrawable; return changed; } Loading @@ -204,6 +207,7 @@ public interface QSTile { sb.append(",isTransient=").append(isTransient); sb.append(",state=").append(state); sb.append(",slash=\"").append(slash).append("\""); sb.append(",sideViewDrawable").append(sideViewDrawable); return sb.append(']'); } Loading
packages/SystemUI/res/layout/qs_tile_label.xml +2 −1 Original line number Diff line number Diff line Loading @@ -16,8 +16,9 @@ --> <com.android.systemui.qs.tileimpl.ButtonRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clipChildren="false" android:clipToPadding="false" android:paddingTop="12dp"> Loading
packages/SystemUI/res/values/dimens.xml +2 −0 Original line number Diff line number Diff line Loading @@ -1437,4 +1437,6 @@ <dimen name="min_wallet_empty_height">208dp</dimen> <dimen name="wallet_card_border_width">1dp</dimen> <dimen name="wallet_empty_state_corner_radius">24dp</dimen> <dimen name="wallet_tile_card_view_height">32dp</dimen> <dimen name="wallet_tile_card_view_width">50dp</dimen> </resources>
packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt +28 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.RippleDrawable import android.service.quicksettings.Tile.STATE_ACTIVE import android.view.Gravity import android.view.View import android.widget.ImageView import android.widget.LinearLayout import android.widget.RelativeLayout import com.android.systemui.R Loading @@ -41,6 +43,7 @@ open class QSTileViewHorizontal( private var paintColor = Color.WHITE private var paintAnimator: ValueAnimator? = null private var labelAnimator: ValueAnimator? = null private var mSideView: ImageView = ImageView(mContext) override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE init { Loading @@ -56,6 +59,14 @@ open class QSTileViewHorizontal( val iconSize = context.resources.getDimensionPixelSize(R.dimen.qs_icon_size) addView(mIcon, 0, LayoutParams(iconSize, iconSize)) mSideView.visibility = View.GONE addView( mSideView, -1, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply { gravity = Gravity.CENTER_VERTICAL }) mColorLabelActive = ColorStateList.valueOf(getColorForState(getContext(), STATE_ACTIVE)) changeLabelColor(getLabelColor(mState)) // Matches the default state of the tile } Loading Loading @@ -128,6 +139,7 @@ open class QSTileViewHorizontal( } paintColor = newColor } loadSideViewDrawableIfNecessary(state) } private fun animateBackground(newBackgroundColor: Int) { Loading Loading @@ -180,5 +192,21 @@ open class QSTileViewHorizontal( labelAnimator?.cancel()?.also { labelAnimator = null } } private fun loadSideViewDrawableIfNecessary(state: QSTile.State) { if (state.sideViewDrawable != null) { (mSideView.layoutParams as MarginLayoutParams).apply { marginStart = context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin) } mSideView.setImageDrawable(state.sideViewDrawable) mSideView.visibility = View.VISIBLE mSideView.adjustViewBounds = true mSideView.scaleType = ImageView.ScaleType.FIT_CENTER } else { mSideView.setImageDrawable(null) mSideView.visibility = GONE } } override fun handleExpand(dualTarget: Boolean) {} } No newline at end of file
packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +65 −0 Original line number Diff line number Diff line Loading @@ -20,11 +20,20 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.WalletCard; import android.service.quicksettings.Tile; import android.util.Log; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; Loading @@ -40,20 +49,29 @@ import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.settings.SecureSettings; import java.util.List; import java.util.concurrent.Executor; import javax.inject.Inject; /** Quick settings tile: Quick access wallet **/ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { private static final String TAG = "QuickAccessWalletTile"; private static final String FEATURE_CHROME_OS = "org.chromium.arc"; private final CharSequence mLabel = mContext.getString(R.string.wallet_title); private final WalletCardRetriever mCardRetriever = new WalletCardRetriever(); // TODO(b/180959290): Re-create the QAW Client when the default NFC payment app changes. private final QuickAccessWalletClient mQuickAccessWalletClient; private final KeyguardStateController mKeyguardStateController; private final PackageManager mPackageManager; private final SecureSettings mSecureSettings; private final Executor mExecutor; private final FeatureFlags mFeatureFlags; @VisibleForTesting Drawable mCardViewDrawable; @Inject public QuickAccessWalletTile( QSHost host, Loading @@ -68,6 +86,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { KeyguardStateController keyguardStateController, PackageManager packageManager, SecureSettings secureSettings, @Background Executor executor, FeatureFlags featureFlags) { super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); Loading @@ -75,6 +94,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { mKeyguardStateController = keyguardStateController; mPackageManager = packageManager; mSecureSettings = secureSettings; mExecutor = executor; mFeatureFlags = featureFlags; } Loading @@ -86,6 +106,14 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { return state; } @Override protected void handleSetListening(boolean listening) { super.handleSetListening(listening); if (listening) { queryWalletCards(); } } @Override protected void handleClick() { mActivityStarter.postStartActivityDismissingKeyguard( Loading @@ -108,6 +136,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { } else { state.state = Tile.STATE_UNAVAILABLE; } state.sideViewDrawable = mCardViewDrawable; } @Override Loading @@ -133,4 +162,40 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { CharSequence qawLabel = mQuickAccessWalletClient.getServiceLabel(); return qawLabel == null ? mLabel : qawLabel; } private void queryWalletCards() { 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= */ 2); mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever); } private class WalletCardRetriever implements QuickAccessWalletClient.OnWalletCardsRetrievedCallback { @Override public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) { Log.i(TAG, "Successfully retrieved wallet cards."); List<WalletCard> cards = response.getWalletCards(); if (cards.isEmpty()) { Log.d(TAG, "No wallet cards exist."); mCardViewDrawable = null; refreshState(); return; } mCardViewDrawable = cards.get(0).getCardImage().loadDrawable(mContext); refreshState(); } @Override public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) { Log.w(TAG, "Error retrieve wallet cards"); mCardViewDrawable = null; refreshState(); } } }