Merge "Wallet on lockscreen" into sc-dev

This commit is contained in:
Matt Pietal
2021-04-13 17:08:09 +00:00
committed by Android (Google) Code Review
7 changed files with 175 additions and 28 deletions

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 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.
*/
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M2.15,1.54h20v21h-20z"/>
<path
android:pathData="M19,21.83H5.35a3.19,3.19 0,0 1,-3.2 -3.19v-7A3.19,3.19 0,0 1,5.35 8.5H19a3.19,3.19 0,0 1,3.19 3.19v7A3.19,3.19 0,0 1,19 21.83ZM5.35,10.44A1.25,1.25 0,0 0,4.1 11.69v7a1.25,1.25 0,0 0,1.25 1.24H19a1.25,1.25 0,0 0,1.25 -1.24v-7A1.25,1.25 0,0 0,19 10.44Z"
android:fillColor="#FF000000" />
<path
android:pathData="M4.7,10.16 L4.21,8.57 16,5a3.56,3.56 0,0 1,3.1 0.25c1,0.67 1.65,2 1.89,4l-1.66,0.2C19.12,8 18.72,7 18.15,6.62a2,2 0,0 0,-1.7 0Z"
android:fillColor="#FF000000" />
<path
android:pathData="M4.43,10.47l-1,-1.34 7.31,-5.44c3,-1.86 5.51,1 6.33,2L15.82,6.77c-2.1,-2.44 -3.23,-2.26 -4.14,-1.7Z"
android:fillColor="#FF000000" />
</group>
</vector>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 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.
*/
-->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:attr/textColorPrimary">
<item>
<shape
android:shape="oval">
<solid android:color="?androidprv:attr/colorSurface"/>
<size
android:width="@dimen/keyguard_affordance_width"
android:height="@dimen/keyguard_affordance_height"/>
</shape>
</item>
</ripple>

View File

@@ -90,9 +90,11 @@
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_gravity="bottom|end"
android:scaleType="center"
android:tint="?attr/wallpaperTextColor"
android:layout_marginStart="24dp"
android:layout_marginBottom="48dp"
android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_wallet_lockscreen"
android:background="@drawable/wallet_lockscreen_bg"
android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:visibility="gone" />
<FrameLayout

View File

@@ -865,9 +865,12 @@
+ 8dp. -->
<dimen name="assist_orb_navbar_scrim_height">56dp</dimen>
<!-- The width/height of the phone/camera icon view on keyguard. -->
<dimen name="keyguard_affordance_height">56dp</dimen>
<dimen name="keyguard_affordance_width">56dp</dimen>
<!-- The width/height of the keyguard bottom area icon view on keyguard. -->
<dimen name="keyguard_affordance_height">48dp</dimen>
<dimen name="keyguard_affordance_width">48dp</dimen>
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
<!-- The width/height of the unlock icon view on keyguard. -->
<dimen name="keyguard_lock_height">42dp</dimen>

View File

@@ -48,8 +48,11 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.service.media.CameraPrewarmService;
import android.service.quickaccesswallet.GetWalletCardsError;
import android.service.quickaccesswallet.GetWalletCardsRequest;
import android.service.quickaccesswallet.GetWalletCardsResponse;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -64,6 +67,8 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -75,6 +80,7 @@ import com.android.systemui.animation.Interpolators;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.camera.CameraIntents;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
@@ -87,6 +93,9 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.wallet.ui.WalletActivity;
import java.util.concurrent.Executor;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
@@ -121,7 +130,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private ImageView mWalletButton;
private boolean mWalletEnabled = false;
private boolean mHasCard = false;
private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
private QuickAccessWalletClient mQuickAccessWalletClient;
private ViewGroup mIndicationArea;
private TextView mIndicationText;
private TextView mIndicationTextBottom;
@@ -138,7 +153,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private AccessibilityController mAccessibilityController;
private StatusBar mStatusBar;
private KeyguardAffordanceHelper mAffordanceHelper;
private FalsingManager mFalsingManager;
private boolean mUserSetupComplete;
private boolean mPrewarmBound;
private Messenger mPrewarmMessenger;
@@ -170,7 +185,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private int mBurnInXOffset;
private int mBurnInYOffset;
private ActivityIntentHelper mActivityIntentHelper;
private int mLockScreenMode;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardBottomAreaView(Context context) {
@@ -415,10 +429,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private void updateWalletVisibility() {
if (mDozing) {
if (mDozing || !mWalletEnabled) {
mWalletButton.setVisibility(GONE);
} else {
mWalletButton.setVisibility(VISIBLE);
mWalletButton.setOnClickListener(this::onWalletClick);
}
}
@@ -871,25 +886,63 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return insets;
}
private void setupWallet() {
boolean inNewLayout = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
boolean settingEnabled = Settings.Global.getInt(mContext.getContentResolver(),
"controls_lockscreen", 0) == 1;
if (!inNewLayout || !settingEnabled) {
mWalletButton.setVisibility(View.GONE);
return;
}
// TODO: add image
// mWalletButton.setImageDrawable(list.get(0).loadIcon());
updateWalletVisibility();
/** Set the falsing manager */
public void setFalsingManager(FalsingManager falsingManager) {
mFalsingManager = falsingManager;
}
/**
* Optionally add controls when in the new lockscreen mode
* Initialize the wallet feature, only enabling if the feature is enabled within the platform.
*/
public void onLockScreenModeChanged(int mode) {
mLockScreenMode = mode;
setupWallet();
public void initWallet(QuickAccessWalletClient client, Executor uiExecutor, boolean enabled) {
mQuickAccessWalletClient = client;
mWalletEnabled = enabled && client.isWalletFeatureAvailable();
if (mWalletEnabled) {
queryWalletCards(uiExecutor);
}
updateWalletVisibility();
}
private void queryWalletCards(Executor uiExecutor) {
GetWalletCardsRequest request =
new GetWalletCardsRequest(1 /* cardWidth */, 1 /* cardHeight */,
1 /* iconSizePx */, 2 /* maxCards */);
mQuickAccessWalletClient.getWalletCards(uiExecutor, request, mCardRetriever);
}
private void onWalletClick(View v) {
// More coming here; need to inform the user about how to proceed
mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY);
if (mHasCard) {
Intent intent = new Intent(mContext, WalletActivity.class)
.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
} else {
if (mQuickAccessWalletClient.createWalletIntent() == null) {
Log.w(TAG, "Could not get intent of the wallet app.");
return;
}
mActivityStarter.postStartActivityDismissingKeyguard(
mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
}
}
private class WalletCardRetriever implements
QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
@Override
public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
mHasCard = !response.getWalletCards().isEmpty();
updateWalletVisibility();
}
@Override
public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
mHasCard = false;
updateWalletVisibility();
}
}
}

View File

@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
@@ -154,6 +155,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -517,6 +519,9 @@ public class NotificationPanelViewController extends PanelViewController {
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
private final QuickAccessWalletClient mQuickAccessWalletClient;
private final Executor mUiExecutor;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -578,7 +583,9 @@ public class NotificationPanelViewController extends PanelViewController {
NotificationShadeDepthController notificationShadeDepthController,
AmbientState ambientState,
LockIconViewController lockIconViewController,
FeatureFlags featureFlags) {
FeatureFlags featureFlags,
QuickAccessWalletClient quickAccessWalletClient,
@Main Executor uiExecutor) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -624,6 +631,8 @@ public class NotificationPanelViewController extends PanelViewController {
mScrimController = scrimController;
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
mQuickAccessWalletClient = quickAccessWalletClient;
mUiExecutor = uiExecutor;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
if (mQs != null) {
mQs.animateHeaderSlidingOut();
@@ -975,6 +984,9 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
mKeyguardBottomArea.setStatusBar(mStatusBar);
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor,
mFeatureFlags.isQuickAccessWalletEnabled());
}
private void updateMaxDisplayedNotifications(boolean recompute) {

View File

@@ -39,6 +39,7 @@ import android.content.res.Resources;
import android.hardware.biometrics.BiometricSourceType;
import android.os.PowerManager;
import android.os.UserManager;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.DisplayMetrics;
@@ -98,6 +99,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
import org.junit.Before;
@@ -235,6 +238,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private LockIconViewController mLockIconViewController;
@Mock
private QuickAccessWalletClient mQuickAccessWalletClient;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -339,7 +344,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationShadeDepthController,
mAmbientState,
mLockIconViewController,
mFeatureFlags);
mFeatureFlags,
mQuickAccessWalletClient,
new FakeExecutor(new FakeSystemClock()));
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);