/* * 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.ui; import static com.android.systemui.wallet.ui.WalletCardCarousel.CARD_ANIM_ALPHA_DELAY; import static com.android.systemui.wallet.ui.WalletCardCarousel.CARD_ANIM_ALPHA_DURATION; import android.annotation.Nullable; import android.app.BroadcastOptions; import android.app.PendingIntent; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.classifier.FalsingCollector; import java.util.List; /** Layout for the wallet screen. */ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCardScrollListener { private static final String TAG = "WalletView"; private static final int CAROUSEL_IN_ANIMATION_DURATION = 100; private static final int CAROUSEL_OUT_ANIMATION_DURATION = 200; private final WalletCardCarousel mCardCarousel; private final ImageView mIcon; private final TextView mCardLabel; // Displays at the bottom of the screen, allow user to enter the default wallet app. private final Button mAppButton; // Displays on the top right of the screen, allow user to enter the default wallet app. private final Button mToolbarAppButton; // Displays underneath the carousel, allow user to unlock device, verify card, etc. private final Button mActionButton; private final Interpolator mOutInterpolator; private final float mAnimationTranslationX; private final ViewGroup mCardCarouselContainer; private final TextView mErrorView; private final ViewGroup mEmptyStateView; private boolean mIsDeviceLocked = false; private boolean mIsUdfpsEnabled = false; private OnClickListener mDeviceLockedActionOnClickListener; private OnClickListener mShowWalletAppOnClickListener; private FalsingCollector mFalsingCollector; public WalletView(Context context) { this(context, null); } public WalletView(Context context, AttributeSet attrs) { super(context, attrs); inflate(context, R.layout.wallet_fullscreen, this); mCardCarouselContainer = requireViewById(R.id.card_carousel_container); mCardCarousel = requireViewById(R.id.card_carousel); mCardCarousel.setCardScrollListener(this); mIcon = requireViewById(R.id.icon); mCardLabel = requireViewById(R.id.label); mAppButton = requireViewById(R.id.wallet_app_button); mToolbarAppButton = requireViewById(R.id.wallet_toolbar_app_button); mActionButton = requireViewById(R.id.wallet_action_button); mErrorView = requireViewById(R.id.error_view); mEmptyStateView = requireViewById(R.id.wallet_empty_state); mOutInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.accelerate_cubic); mAnimationTranslationX = mCardCarousel.getCardWidthPx() / 4f; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mCardCarousel.setExpectedViewWidth(getWidth()); } private void updateViewForOrientation(@Configuration.Orientation int orientation) { if (orientation == Configuration.ORIENTATION_PORTRAIT) { renderViewPortrait(); } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) { renderViewLandscape(); } mCardCarousel.resetAdapter(); // necessary to update cards width ViewGroup.LayoutParams params = mCardCarouselContainer.getLayoutParams(); if (params instanceof MarginLayoutParams) { ((MarginLayoutParams) params).topMargin = getResources().getDimensionPixelSize( R.dimen.wallet_card_carousel_container_top_margin); } } private void renderViewPortrait() { mAppButton.setVisibility(VISIBLE); mToolbarAppButton.setVisibility(GONE); mCardLabel.setVisibility(VISIBLE); requireViewById(R.id.dynamic_placeholder).setVisibility(VISIBLE); mAppButton.setOnClickListener(mShowWalletAppOnClickListener); } private void renderViewLandscape() { mToolbarAppButton.setVisibility(VISIBLE); mAppButton.setVisibility(GONE); mCardLabel.setVisibility(GONE); requireViewById(R.id.dynamic_placeholder).setVisibility(GONE); mToolbarAppButton.setOnClickListener(mShowWalletAppOnClickListener); } @Override public boolean onTouchEvent(MotionEvent event) { // Forward touch events to card carousel to allow for swiping outside carousel bounds. return mCardCarousel.onTouchEvent(event) || super.onTouchEvent(event); } @Override public void onCardScroll(WalletCardViewInfo centerCard, WalletCardViewInfo nextCard, float percentDistanceFromCenter) { CharSequence centerCardText = getLabelText(centerCard); Drawable centerCardIcon = getHeaderIcon(mContext, centerCard); renderActionButton(centerCard, mIsDeviceLocked, mIsUdfpsEnabled); if (centerCard.isUiEquivalent(nextCard)) { mCardLabel.setAlpha(1f); mIcon.setAlpha(1f); mActionButton.setAlpha(1f); } else { mCardLabel.setText(centerCardText); mIcon.setImageDrawable(centerCardIcon); mCardLabel.setAlpha(percentDistanceFromCenter); mIcon.setAlpha(percentDistanceFromCenter); mActionButton.setAlpha(percentDistanceFromCenter); } } /** * Render and show card carousel view. * *
This is called only when {@param data} is not empty.
* * @param data a list of wallet cards information. * @param selectedIndex index of the current selected card * @param isDeviceLocked indicates whether the device is locked. */ void showCardCarousel( List